From 7a6e93788cda1f9ead6b4fdb25ea72b7a434eddd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Dec 2010 00:40:44 +0100 Subject: [PATCH 001/315] ZFS zlib compression support --- grub-core/fs/zfs/zfs.c | 22 ++++++++++++++++++++-- include/grub/zfs/zio.h | 10 +++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8901af76f..d7bf2bc30 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -51,6 +51,7 @@ #include #include #include +#include #define ZPOOL_PROP_BOOTFS "bootfs" @@ -161,13 +162,30 @@ struct grub_zfs_data grub_disk_addr_t vdev_phys_sector; }; +static grub_err_t +zlib_decompress (void *s, void *d, + grub_size_t slen, grub_size_t dlen) +{ + if (grub_zlib_decompress (s, slen, 0, d, dlen) < 0) + return grub_errno; + return GRUB_ERR_NONE; +} + decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ {"off", NULL}, /* ZIO_COMPRESS_OFF */ {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ - {"gzip", NULL}, /* ZIO_COMPRESS_GZIP */ + {"gzip-1", zlib_decompress}, /* ZIO_COMPRESS_GZIP1 */ + {"gzip-2", zlib_decompress}, /* ZIO_COMPRESS_GZIP2 */ + {"gzip-3", zlib_decompress}, /* ZIO_COMPRESS_GZIP3 */ + {"gzip-4", zlib_decompress}, /* ZIO_COMPRESS_GZIP4 */ + {"gzip-5", zlib_decompress}, /* ZIO_COMPRESS_GZIP5 */ + {"gzip-6", zlib_decompress}, /* ZIO_COMPRESS_GZIP6 */ + {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ + {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ + {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, @@ -525,7 +543,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, *buf = NULL; checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; - comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7; + comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 797d4f9b3..3dafb4028 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -77,7 +77,15 @@ enum zio_compress { ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, - ZIO_COMPRESS_GZIP, + ZIO_COMPRESS_GZIP1, + ZIO_COMPRESS_GZIP2, + ZIO_COMPRESS_GZIP3, + ZIO_COMPRESS_GZIP4, + ZIO_COMPRESS_GZIP5, + ZIO_COMPRESS_GZIP6, + ZIO_COMPRESS_GZIP7, + ZIO_COMPRESS_GZIP8, + ZIO_COMPRESS_GZIP9, ZIO_COMPRESS_FUNCTIONS }; From c5cf9f53a839f38405fd9fe10999c3231c30322a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Dec 2010 01:59:06 +0100 Subject: [PATCH 002/315] Fix short symlinks --- grub-core/fs/zfs/zfs.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index d7bf2bc30..8f20085fa 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1306,22 +1306,27 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; -#if 0 - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) + if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *oldpath = path, *oldpathbuf = path_buf; + grub_size_t bonuslen; + bonuslen = (grub_uint8_t *) (&dnode_path->dn.dn + 1) + - (grub_uint8_t *) DN_BONUS (&dnode_path->dn.dn); + if (bonuslen <= sizeof (znode_phys_t)) + err = grub_error (GRUB_ERR_BAD_FS, + "incorrect or unsupported symlink"); path = path_buf - = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) - - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); + = grub_malloc (bonuslen - sizeof (znode_phys_t) + + grub_strlen (oldpath) + 1); if (!path_buf) { grub_free (oldpathbuf); return grub_errno; } - grub_memcpy (path, - (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), - sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); - path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; + grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) + + sizeof (znode_phys_t), + bonuslen - sizeof (znode_phys_t)); + path[bonuslen - sizeof (znode_phys_t)] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); @@ -1339,7 +1344,6 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } -#endif } if (!err) From fe79a8ad9db01795baccfc28525a5d75f03d0959 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 15:35:08 +0100 Subject: [PATCH 003/315] Fix fzap handling --- grub-core/fs/zfs/zfs.c | 4 +++- include/grub/zfs/zap_leaf.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8f20085fa..c47b4afc9 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -961,7 +961,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); return 0; } - for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) + for (idx = 0; idx < grub_zfs_to_cpu64 (zap->zap_num_leafs, + zap_dnode->endian); idx++) { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; @@ -2553,6 +2554,7 @@ static struct grub_fs grub_zfs_fs = { GRUB_MOD_INIT (zfs) { + COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE); grub_fs_register (&grub_zfs_fs); #ifndef GRUB_UTIL my_mod = mod; diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 1ef654054..5adfdc290 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -90,7 +90,7 @@ typedef union zap_leaf_chunk { { grub_uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; grub_uint64_t la_array64; - }; + } __attribute__ ((packed)); grub_uint16_t la_next; /* next blk or CHAIN_END */ } l_array; struct zap_leaf_free { From 47c3603cc8deeae7bf03bb7fc6756d9c58fe5e00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 15:41:17 +0100 Subject: [PATCH 004/315] Add missing endianness conversions in fzap code --- grub-core/fs/zfs/zfs.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index c47b4afc9..62d7051ef 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -831,7 +831,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian); - chunk != CHAIN_END; chunk = le->le_next) + chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian)) { if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) @@ -856,7 +856,8 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, struct zap_leaf_array *la; grub_uint8_t *ip; - if (le->le_int_size != 8 || le->le_value_length != 1) + if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length, + endian) != 1) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); /* get the uint64_t property value */ @@ -875,9 +876,9 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, /* Verify if this is a fat zap header block */ static grub_err_t -zap_verify (zap_phys_t *zap) +zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) { - if (zap->zap_magic != (grub_uint64_t) ZAP_MAGIC) + if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); if (zap->zap_flags != 0) @@ -905,7 +906,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_err_t err; grub_zfs_endian_t leafendian; - err = zap_verify (zap); + err = zap_verify (zap, zap_dnode->endian); if (err) return err; @@ -916,7 +917,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "external pointer tables not supported"); idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift); - blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], zap_dnode->endian); /* Get the leaf block */ if ((1U << blksft) < sizeof (zap_leaf_phys_t)) @@ -945,7 +946,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_err_t err; grub_zfs_endian_t endian; - if (zap_verify (zap)) + if (zap_verify (zap, zap_dnode->endian)) return 0; /* get block id from index */ @@ -964,7 +965,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, for (idx = 0; idx < grub_zfs_to_cpu64 (zap->zap_num_leafs, zap_dnode->endian); idx++) { - blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], + zap_dnode->endian); err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data); if (err) @@ -999,8 +1001,11 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + 1); - if (zap_leaf_array_get (l, endian, blksft, le->le_name_chunk, - le->le_name_length, buf)) + if (zap_leaf_array_get (l, endian, blksft, + grub_zfs_to_cpu16 (le->le_name_chunk, + endian), + grub_zfs_to_cpu16 (le->le_name_length, + endian), buf)) { grub_free (buf); continue; @@ -1012,7 +1017,9 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, continue; /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; + la = &ZAP_LEAF_CHUNK (l, blksft, + grub_zfs_to_cpu16 (le->le_value_chunk, + endian)).l_array; val = grub_be_to_cpu64 (la->la_array64); if (hook (buf, val)) return 1; From 069142f4c2cd0eab6528a4abfc955b308c47d113 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 16:08:26 +0100 Subject: [PATCH 005/315] Support long symlinks --- grub-core/fs/zfs/zfs.c | 47 +++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 62d7051ef..bf955a930 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1323,18 +1323,45 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, if (bonuslen <= sizeof (znode_phys_t)) err = grub_error (GRUB_ERR_BAD_FS, "incorrect or unsupported symlink"); - path = path_buf - = grub_malloc (bonuslen - sizeof (znode_phys_t) - + grub_strlen (oldpath) + 1); - if (!path_buf) + if (dnode_path->dn.dn.dn_flags & 1) { - grub_free (oldpathbuf); - return grub_errno; + void *sbuf; + grub_size_t ssize; + err = zio_read (dnode_path->dn.dn.dn_blkptr, + dnode_path->dn.endian, &sbuf, + &ssize, data); + if (err) + { + grub_free (oldpathbuf); + return err; + } + + path = path_buf = grub_malloc (ssize+ grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + grub_free (sbuf); + return grub_errno; + } + grub_memcpy (path, sbuf, ssize); + path[ssize] = 0; + grub_free (sbuf); + } + else + { + path = path_buf + = grub_malloc (bonuslen - sizeof (znode_phys_t) + + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + return grub_errno; + } + grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) + + sizeof (znode_phys_t), + bonuslen - sizeof (znode_phys_t)); + path[bonuslen - sizeof (znode_phys_t)] = 0; } - grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) - + sizeof (znode_phys_t), - bonuslen - sizeof (znode_phys_t)); - path[bonuslen - sizeof (znode_phys_t)] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); From e5c63d9d4183e40f155e84f3313b9f1490064659 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 18:13:32 +0100 Subject: [PATCH 006/315] Fix handling of nvlist array --- grub-core/fs/zfs/zfs.c | 48 ++++++++++++++++++++++++-------------- grub-core/fs/zfs/zfsinfo.c | 2 +- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index bf955a930..670326a42 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1812,13 +1812,28 @@ grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) grub_size_t nelm, size; int found; - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, &size, &nelm); if (! found) return -1; return nelm; } +static int +get_nvlist_size (char *beg, char *limit) +{ + char *ptr; + grub_uint32_t encode_size; + + ptr = beg + 8; + + while (ptr < limit + && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) ptr))) + ptr += encode_size; /* goto the next nvpair */ + ptr += 8; + return (ptr > limit) ? -1 : (ptr - beg); +} + char * grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t index) @@ -1829,8 +1844,9 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t size; unsigned i; grub_size_t nelm; + int elemsize = 0; - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, &size, &nelm); if (!found) return 0; @@ -1844,33 +1860,31 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, for (i = 0; i < index; i++) { - grub_uint32_t encode_size; + int r; + r = get_nvlist_size (nvpairptr, nvpair + size); - /* skip the header, nvl_version, and nvl_nvflag */ - nvpairptr = nvpairptr + 4 * 2; - - while (nvpairptr < nvpair + size - && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvpairptr))) - nvlist += encode_size; /* goto the next nvpair */ - - nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */ + if (r < 0) + { + grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); + return NULL; + } + nvpairptr += r; } - if (nvpairptr >= nvpair + size - || nvpairptr + grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) - >= nvpair + size) + elemsize = get_nvlist_size (nvpairptr, nvpair + size); + + if (elemsize < 0) { grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); return 0; } - ret = grub_zalloc (grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) - + 3 * sizeof (grub_uint32_t)); + ret = grub_zalloc (elemsize + sizeof (grub_uint32_t)); if (!ret) return 0; grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); - grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, size); + grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, elemsize); return ret; } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 33065892a..735b8e983 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -139,7 +139,6 @@ print_vdev_info (char *nvlist, int tab) } grub_printf ("Mirror VDEV with %d children\n", nelm); print_state (nvlist, tab); - for (i = 0; i < nelm; i++) { char *child; @@ -159,6 +158,7 @@ print_vdev_info (char *nvlist, int tab) grub_free (child); } + return GRUB_ERR_NONE; } print_tabs (tab); From fdfde32aa4f1d4ce00d86cf481401cf215b8861e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 21:17:24 +0100 Subject: [PATCH 007/315] striped zpool support --- Makefile.util.def | 1 + grub-core/fs/zfs/zfs.c | 659 +++++++++++++++++++++++++---------------- util/grub-fstest.c | 8 + 3 files changed, 412 insertions(+), 256 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 2dd7fe1e9..0e2e0afa8 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -71,6 +71,7 @@ library = { common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; common = grub-core/fs/zfs/zfs.c; + common = grub-core/fs/zfs/zfsinfo.c; common = grub-core/fs/zfs/zfs_lzjb.c; common = grub-core/fs/zfs/zfs_sha256.c; common = grub-core/fs/zfs/zfs_fletcher.c; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 670326a42..3163e2e78 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -138,6 +138,15 @@ typedef struct dnode_end grub_zfs_endian_t endian; } dnode_end_t; +struct grub_zfs_device_desc +{ + enum { DEVICE_LEAF } type; + grub_disk_t disk; + grub_uint64_t id; + grub_disk_addr_t vdev_phys_sector; + uberblock_t current_uberblock; +}; + struct grub_zfs_data { /* cache for a file block of the currently zfs_open()-ed file */ @@ -152,14 +161,16 @@ struct grub_zfs_data grub_uint64_t dnode_end; grub_zfs_endian_t dnode_endian; - uberblock_t current_uberblock; - grub_disk_t disk; - dnode_end_t mos; dnode_end_t mdn; dnode_end_t dnode; - grub_disk_addr_t vdev_phys_sector; + struct grub_zfs_device_desc *devices_attached; + unsigned n_devices_attached; + unsigned n_devices_allocated; + + int mounted; + grub_uint64_t guid; }; static grub_err_t @@ -408,7 +419,7 @@ get_psize (blkptr_t * bp, grub_zfs_endian_t endian) } static grub_uint64_t -dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) +dva_get_offset (const dva_t *dva, grub_zfs_endian_t endian) { grub_dprintf ("zfs", "dva=%llx, %llx\n", (unsigned long long) dva->dva_word[0], @@ -417,6 +428,356 @@ dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) endian) << SPA_MINBLOCKSHIFT; } +static grub_err_t +zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) +{ + grub_err_t err; + + *nvlist = grub_malloc (VDEV_PHYS_SIZE); + /* Read in the vdev name-value pair list (112K). */ + err = grub_disk_read (diskdesc->disk, diskdesc->vdev_phys_sector, 0, + VDEV_PHYS_SIZE, *nvlist); + if (err) + { + grub_free (*nvlist); + *nvlist = 0; + return err; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +fill_vdev_info (char *nvlist, struct grub_zfs_device_desc *diskdesc) +{ + char *type = 0; + + type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); + + if (!type) + return grub_errno; + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + { + diskdesc->type = DEVICE_LEAF; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &diskdesc->id)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", + type); +} + +/* + * Check the disk label information and retrieve needed vdev name-value pairs. + * + */ +static grub_err_t +check_pool_label (struct grub_zfs_data *data, + struct grub_zfs_device_desc *diskdesc, + grub_uint64_t *id) +{ + grub_uint64_t pool_state, txg = 0; + char *nvlist; +#if 0 + char *nv; +#endif + grub_uint64_t diskguid, poolguid; + grub_uint64_t version; + int found; + grub_err_t err; + + err = zfs_fetch_nvlist (diskdesc, &nvlist); + if (err) + return err; + + grub_dprintf ("zfs", "check 2 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, + &pool_state); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 3 passed\n"); + + if (pool_state == POOL_STATE_DESTROYED) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); + } + grub_dprintf ("zfs", "check 4 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); + if (!found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 6 passed\n"); + + /* not an active device */ + if (txg == 0) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); + } + grub_dprintf ("zfs", "check 7 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, + &version); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 8 passed\n"); + + if (version > SPA_VERSION) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "too new version %llu > %llu", + (unsigned long long) version, + (unsigned long long) SPA_VERSION); + } + grub_dprintf ("zfs", "check 9 passed\n"); + + { + char *nv; + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (!nv) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); + } + err = fill_vdev_info (nv, diskdesc); + if (err) + { + grub_free (nvlist); + return err; + } + } + grub_dprintf ("zfs", "check 10 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); + return grub_errno; + } + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, + &poolguid); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_GUID " not found"); + return grub_errno; + } + + grub_dprintf ("zfs", "check 11 passed\n"); + + if (data->mounted && data->guid != poolguid) + return grub_error (GRUB_ERR_BAD_FS, "another zpool"); + else + data->guid = poolguid; + grub_free (nvlist); + + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + data->devices_attached = tmp; + return grub_errno; + } + } + + data->devices_attached[data->n_devices_attached - 1] = *diskdesc; + if (id) + *id = diskdesc->id; + + return GRUB_ERR_NONE; +} + +static grub_err_t +scan_disk (grub_disk_t disk, struct grub_zfs_data *data, + grub_uint64_t *id) +{ + int label = 0; + uberblock_phys_t *ub_array, *ubbest = NULL; + vdev_boot_header_t *bh; + grub_err_t err; + int vdevnum; + struct grub_zfs_device_desc desc; + + ub_array = grub_malloc (VDEV_UBERBLOCK_RING); + if (!ub_array) + return grub_errno; + + bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); + if (!bh) + { + grub_free (ub_array); + return grub_errno; + } + + vdevnum = VDEV_LABELS; + + desc.disk = disk; + + /* Don't check back labels on CDROM. */ + if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN) + vdevnum = VDEV_LABELS / 2; + + for (label = 0; ubbest == NULL && label < vdevnum; label++) + { + grub_dprintf ("zfs", "label %d\n", label); + + desc.vdev_phys_sector + = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) + + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (disk) + - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); + + /* Read in the uberblock ring (128K). */ + err = grub_disk_read (disk, desc.vdev_phys_sector + + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), + 0, VDEV_UBERBLOCK_RING, (char *) ub_array); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_dprintf ("zfs", "label ok %d\n", label); + + ubbest = find_bestub (ub_array, desc.vdev_phys_sector); + if (!ubbest) + { + grub_dprintf ("zfs", "No uberblock found\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + + grub_memmove (&(desc.current_uberblock), + &ubbest->ubp_uberblock, sizeof (uberblock_t)); + + err = check_pool_label (data, &desc, id); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } +#if 0 + if (find_best_root && + vdev_uberblock_compare (&ubbest->ubp_uberblock, + &(current_uberblock)) <= 0) + continue; +#endif + grub_free (ub_array); + grub_free (bh); + return GRUB_ERR_NONE; + } + + grub_free (ub_array); + grub_free (bh); + + return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); +} + +static grub_err_t +scan_devices (struct grub_zfs_data *data, grub_uint64_t id) +{ + grub_device_t dev_found = NULL; + auto int hook (const char *name); + int hook (const char *name) + { + grub_device_t dev; + grub_err_t err; + grub_uint64_t f_id = -1; + dev = grub_device_open (name); + if (!dev) + return 0; + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + err = scan_disk (dev->disk, data, &f_id); + if (err == GRUB_ERR_BAD_FS) + { + grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (err) + { + grub_device_close (dev); + grub_print_error (); + return 0; + } + if (f_id != id) + { + grub_device_close (dev); + return 0; + } + + dev_found = dev; + return 1; + } + grub_device_iterate (hook); + if (!dev_found) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find device 0x%" PRIxGRUB_UINT64_T, id); + return GRUB_ERR_NONE; +} + +static grub_err_t +read_dva (const dva_t *dva, + grub_zfs_endian_t endian, struct grub_zfs_data *data, + void *buf, grub_size_t len) +{ + grub_uint64_t offset, sector; + unsigned i; + grub_err_t err; + int try = 0; + + for (try = 0; try < 1; try++) + { + for (i = 0; i < data->n_devices_attached; i++) + if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) + { + /* read in a data block */ + offset = dva_get_offset (dva, endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + return grub_disk_read (data->devices_attached[i].disk, sector, + 0, len, buf); + } + err = scan_devices (data, DVA_GET_VDEV (dva)); + if (err) + return err; + } + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find device 0x%" PRIxGRUB_UINT64_T, + DVA_GET_VDEV (dva)); +} /* * Read a block of data based on the gang block address dva, @@ -428,7 +789,6 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, struct grub_zfs_data *data) { zio_gbh_phys_t *zio_gb; - grub_uint64_t offset, sector; unsigned i; grub_err_t err; zio_cksum_t zc; @@ -440,13 +800,8 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, return grub_errno; grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" :"big-endian gang\n"); - offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - grub_dprintf ("zfs", "offset=%llx\n", (unsigned long long) offset); - /* read in the gang block header */ - err = grub_disk_read (data->disk, sector, 0, SPA_GANGBLOCKSIZE, - (char *) zio_gb); + err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE); if (err) { grub_free (zio_gb); @@ -499,20 +854,13 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, /* pick a good dva from the block pointer */ for (i = 0; i < SPA_DVAS_PER_BP; i++) { - grub_uint64_t offset, sector; - if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0) continue; if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1) err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data); else - { - /* read in a data block */ - offset = dva_get_offset (&bp->blk_dva[i], endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - err = grub_disk_read (data->disk, sector, 0, psize, buf); - } + err = read_dva (&bp->blk_dva[i], endian, data, buf, psize); if (!err) return GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE; @@ -1888,128 +2236,6 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, return ret; } -static grub_err_t -zfs_fetch_nvlist (struct grub_zfs_data * data, char **nvlist) -{ - grub_err_t err; - - *nvlist = grub_malloc (VDEV_PHYS_SIZE); - /* Read in the vdev name-value pair list (112K). */ - err = grub_disk_read (data->disk, data->vdev_phys_sector, 0, - VDEV_PHYS_SIZE, *nvlist); - if (err) - { - grub_free (*nvlist); - *nvlist = 0; - return err; - } - return GRUB_ERR_NONE; -} - -/* - * Check the disk label information and retrieve needed vdev name-value pairs. - * - */ -static grub_err_t -check_pool_label (struct grub_zfs_data *data) -{ - grub_uint64_t pool_state, txg = 0; - char *nvlist; -#if 0 - char *nv; -#endif - grub_uint64_t diskguid; - grub_uint64_t version; - int found; - grub_err_t err; - - err = zfs_fetch_nvlist (data, &nvlist); - if (err) - return err; - - grub_dprintf ("zfs", "check 2 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, - &pool_state); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 3 passed\n"); - - if (pool_state == POOL_STATE_DESTROYED) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); - } - grub_dprintf ("zfs", "check 4 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); - if (!found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 6 passed\n"); - - /* not an active device */ - if (txg == 0) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); - } - grub_dprintf ("zfs", "check 7 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, - &version); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 8 passed\n"); - - if (version > SPA_VERSION) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "too new version %llu > %llu", - (unsigned long long) version, - (unsigned long long) SPA_VERSION); - } - grub_dprintf ("zfs", "check 9 passed\n"); -#if 0 - if (nvlist_lookup_value (nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv, - DATA_TYPE_NVLIST, NULL)) - { - grub_free (vdev); - return (GRUB_ERR_BAD_FS); - } - grub_dprintf ("zfs", "check 10 passed\n"); -#endif - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 11 passed\n"); - - grub_free (nvlist); - - return GRUB_ERR_NONE; -} - static void zfs_unmount (struct grub_zfs_data *data) { @@ -2028,13 +2254,11 @@ static struct grub_zfs_data * zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; - int label = 0; - uberblock_phys_t *ub_array, *ubbest = NULL; - vdev_boot_header_t *bh; + grub_err_t err; objset_phys_t *osp = 0; grub_size_t ospsize; - grub_err_t err; - int vdevnum; + grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + uberblock_t *ub; if (! dev->disk) { @@ -2042,118 +2266,56 @@ zfs_mount (grub_device_t dev) return 0; } - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data)); if (!data) return 0; - grub_memset (data, 0, sizeof (*data)); #if 0 /* if it's our first time here, zero the best uberblock out */ if (data->best_drive == 0 && data->best_part == 0 && find_best_root) grub_memset (¤t_uberblock, 0, sizeof (uberblock_t)); #endif - data->disk = dev->disk; - - ub_array = grub_malloc (VDEV_UBERBLOCK_RING); - if (!ub_array) + data->n_devices_allocated = 16; + data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) + * data->n_devices_allocated); + data->n_devices_attached = 0; + err = scan_disk (dev->disk, data, NULL); + if (err) { zfs_unmount (data); - return 0; + return NULL; } - bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); - if (!bh) + ub = &(data->devices_attached[0].current_uberblock); + ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, + LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? LITTLE_ENDIAN : BIG_ENDIAN); + + err = zio_read (&ub->ub_rootbp, ub_endian, + (void **) &osp, &ospsize, data); + if (err) { zfs_unmount (data); - grub_free (ub_array); - return 0; + return NULL; } - vdevnum = VDEV_LABELS; - - /* Don't check back labels on CDROM. */ - if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) - vdevnum = VDEV_LABELS / 2; - - for (label = 0; ubbest == NULL && label < vdevnum; label++) + if (ospsize < OBJSET_PHYS_SIZE_V14) { - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; - grub_dprintf ("zfs", "label %d\n", label); - - data->vdev_phys_sector - = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) - + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) - + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) - - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); - - /* Read in the uberblock ring (128K). */ - err = grub_disk_read (data->disk, data->vdev_phys_sector - + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), - 0, VDEV_UBERBLOCK_RING, (char *) ub_array); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - grub_dprintf ("zfs", "label ok %d\n", label); - - ubbest = find_bestub (ub_array, data->vdev_phys_sector); - if (!ubbest) - { - grub_dprintf ("zfs", "No uberblock found\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - ub_endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); - err = zio_read (&ubbest->ubp_uberblock.ub_rootbp, - ub_endian, - (void **) &osp, &ospsize, data); - if (err) - { - grub_dprintf ("zfs", "couldn't zio_read\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - - if (ospsize < OBJSET_PHYS_SIZE_V14) - { - grub_dprintf ("zfs", "osp too small\n"); - grub_free (osp); - continue; - } - grub_dprintf ("zfs", "ubbest %p\n", ubbest); - - err = check_pool_label (data); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } -#if 0 - if (find_best_root && - vdev_uberblock_compare (&ubbest->ubp_uberblock, - &(current_uberblock)) <= 0) - continue; -#endif - /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); - data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1; - grub_memmove (&(data->current_uberblock), - &ubbest->ubp_uberblock, sizeof (uberblock_t)); - grub_free (ub_array); - grub_free (bh); + grub_error (GRUB_ERR_BAD_FS, "OSP too small"); grub_free (osp); - return data; + zfs_unmount (data); + return NULL; } - grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); - zfs_unmount (data); - grub_free (ub_array); - grub_free (bh); + + /* Got the MOS. Save it at the memory addr MOS. */ + grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop, + ub_endian) >> 63) & 1; grub_free (osp); - return 0; + data->mounted = 1; + + return data; } grub_err_t @@ -2165,7 +2327,7 @@ grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) zfs = zfs_mount (dev); if (!zfs) return grub_errno; - err = zfs_fetch_nvlist (zfs, nvlist); + err = zfs_fetch_nvlist (&zfs->devices_attached[0], nvlist); zfs_unmount (zfs); return err; } @@ -2181,7 +2343,7 @@ zfs_label (grub_device_t device, char **label) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data, &nvlist); + err = zfs_fetch_nvlist (data->devices_attached, &nvlist); if (err) { zfs_unmount (data); @@ -2197,11 +2359,7 @@ zfs_label (grub_device_t device, char **label) static grub_err_t zfs_uuid (grub_device_t device, char **uuid) { - char *nvlist; - int found; struct grub_zfs_data *data; - grub_uint64_t guid; - grub_err_t err; *uuid = 0; @@ -2209,18 +2367,7 @@ zfs_uuid (grub_device_t device, char **uuid) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data, &nvlist); - if (err) - { - zfs_unmount (data); - return err; - } - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); - if (! found) - return grub_errno; - grub_free (nvlist); - *uuid = grub_xasprintf ("%016llx", (long long unsigned) guid); + *uuid = grub_xasprintf ("%016llx", (long long unsigned) data->guid); zfs_unmount (data); if (! *uuid) return grub_errno; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 2fcde4ab0..122465d7a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -60,6 +60,7 @@ execute_command (char *name, int n, char **args) #define CMD_HEX 4 #define CMD_CRC 6 #define CMD_BLOCKLIST 7 +#define CMD_ZFSINFO 8 #define BUF_SIZE 32256 @@ -309,6 +310,9 @@ fstest (int n, char **args) case CMD_LS: execute_command ("ls", n, args); break; + case CMD_ZFSINFO: + execute_command ("zfsinfo", n, args); + break; case CMD_CP: cmd_cp (args[0], args[1]); break; @@ -454,6 +458,10 @@ argp_parser (int key, char *arg, struct argp_state *state) { cmd = CMD_LS; } + else if (!grub_strcmp (arg, "zfsinfo")) + { + cmd = CMD_ZFSINFO; + } else if (!grub_strcmp (arg, "cp")) { cmd = CMD_CP; From 8ff84951c5c8d09011caec8bf77c67e55414ec30 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 02:31:22 +0100 Subject: [PATCH 008/315] ZFS mirror support --- grub-core/fs/zfs/zfs.c | 299 +++++++++++++++++++++++++++++------------ include/grub/zfs/zfs.h | 12 +- 2 files changed, 221 insertions(+), 90 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3163e2e78..b5f25473f 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -140,11 +140,19 @@ typedef struct dnode_end struct grub_zfs_device_desc { - enum { DEVICE_LEAF } type; - grub_disk_t disk; + enum { DEVICE_LEAF, DEVICE_MIRROR } type; grub_uint64_t id; + grub_uint64_t guid; + + /* Valid only for non-leafs. */ + unsigned n_children; + struct grub_zfs_device_desc *children; + + /* Valid only for leaf devices. */ + grub_device_t dev; grub_disk_addr_t vdev_phys_sector; uberblock_t current_uberblock; + int original; }; struct grub_zfs_data @@ -169,6 +177,8 @@ struct grub_zfs_data unsigned n_devices_attached; unsigned n_devices_allocated; + uberblock_t current_uberblock; + int mounted; grub_uint64_t guid; }; @@ -434,8 +444,11 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) grub_err_t err; *nvlist = grub_malloc (VDEV_PHYS_SIZE); + if (!diskdesc->dev) + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + /* Read in the vdev name-value pair list (112K). */ - err = grub_disk_read (diskdesc->disk, diskdesc->vdev_phys_sector, 0, + err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0, VDEV_PHYS_SIZE, *nvlist); if (err) { @@ -447,41 +460,129 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) } static grub_err_t -fill_vdev_info (char *nvlist, struct grub_zfs_device_desc *diskdesc) +fill_vdev_info_real (const char *nvlist, + struct grub_zfs_device_desc *fill, + struct grub_zfs_device_desc *insert) { - char *type = 0; + char *type; type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); if (!type) return grub_errno; + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id))) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) { - diskdesc->type = DEVICE_LEAF; - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &diskdesc->id)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + fill->type = DEVICE_LEAF; + + if (!fill->dev && fill->guid == insert->guid) + { + fill->dev = insert->dev; + fill->vdev_phys_sector = insert->vdev_phys_sector; + fill->current_uberblock = insert->current_uberblock; + fill->original = insert->original; + } return GRUB_ERR_NONE; } + + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + { + int nelm, i; + + fill->type = DEVICE_MIRROR; + + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); + + if (nelm <= 0) + return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + + fill->n_children = nelm; + + fill->children = grub_zalloc (fill->n_children + * sizeof (fill->children[0])); + + for (i = 0; i < nelm; i++) + { + char *child; + grub_err_t err; + + child = grub_zfs_nvlist_lookup_nvlist_array + (nvlist, ZPOOL_CONFIG_CHILDREN, i); + + err = fill_vdev_info_real (child, &fill->children[i], insert); + + grub_free (child); + + if (err) + return err; + } + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type); } +static grub_err_t +fill_vdev_info (struct grub_zfs_data *data, + char *nvlist, struct grub_zfs_device_desc *diskdesc) +{ + grub_uint64_t id; + unsigned i; + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + for (i = 0; i < data->n_devices_attached; i++) + if (data->devices_attached[i].id == id) + return fill_vdev_info_real (nvlist, &data->devices_attached[i], + diskdesc); + + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + data->devices_attached = tmp; + return grub_errno; + } + } + + grub_memset (&data->devices_attached[data->n_devices_attached - 1], + 0, sizeof (data->devices_attached[data->n_devices_attached - 1])); + + return fill_vdev_info_real (nvlist, + &data->devices_attached[data->n_devices_attached - 1], + diskdesc); +} + /* * Check the disk label information and retrieve needed vdev name-value pairs. * */ static grub_err_t check_pool_label (struct grub_zfs_data *data, - struct grub_zfs_device_desc *diskdesc, - grub_uint64_t *id) + struct grub_zfs_device_desc *diskdesc) { grub_uint64_t pool_state, txg = 0; char *nvlist; #if 0 char *nv; #endif - grub_uint64_t diskguid, poolguid; + grub_uint64_t poolguid; grub_uint64_t version; int found; grub_err_t err; @@ -549,25 +650,8 @@ check_pool_label (struct grub_zfs_data *data, } grub_dprintf ("zfs", "check 9 passed\n"); - { - char *nv; - nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); - - if (!nv) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); - } - err = fill_vdev_info (nv, diskdesc); - if (err) - { - grub_free (nvlist); - return err; - } - } - grub_dprintf ("zfs", "check 10 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, + &(diskdesc->guid)); if (! found) { grub_free (nvlist); @@ -592,34 +676,33 @@ check_pool_label (struct grub_zfs_data *data, return grub_error (GRUB_ERR_BAD_FS, "another zpool"); else data->guid = poolguid; + + { + char *nv; + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (!nv) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); + } + err = fill_vdev_info (data, nv, diskdesc); + if (err) + { + grub_free (nvlist); + return err; + } + } + grub_dprintf ("zfs", "check 10 passed\n"); + grub_free (nvlist); - data->n_devices_attached++; - if (data->n_devices_attached > data->n_devices_allocated) - { - void *tmp; - data->n_devices_allocated = 2 * data->n_devices_attached + 1; - data->devices_attached - = grub_realloc (tmp = data->devices_attached, - data->n_devices_allocated - * sizeof (data->devices_attached[0])); - if (!data->devices_attached) - { - data->devices_attached = tmp; - return grub_errno; - } - } - - data->devices_attached[data->n_devices_attached - 1] = *diskdesc; - if (id) - *id = diskdesc->id; - return GRUB_ERR_NONE; } static grub_err_t -scan_disk (grub_disk_t disk, struct grub_zfs_data *data, - grub_uint64_t *id) +scan_disk (grub_device_t dev, struct grub_zfs_data *data, + int original) { int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; @@ -641,24 +724,23 @@ scan_disk (grub_disk_t disk, struct grub_zfs_data *data, vdevnum = VDEV_LABELS; - desc.disk = disk; + desc.dev = dev; + desc.original = original; /* Don't check back labels on CDROM. */ - if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN) + if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) vdevnum = VDEV_LABELS / 2; for (label = 0; ubbest == NULL && label < vdevnum; label++) { - grub_dprintf ("zfs", "label %d\n", label); - desc.vdev_phys_sector = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) - + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (disk) + + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); /* Read in the uberblock ring (128K). */ - err = grub_disk_read (disk, desc.vdev_phys_sector + err = grub_disk_read (dev->disk, desc.vdev_phys_sector + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), 0, VDEV_UBERBLOCK_RING, (char *) ub_array); if (err) @@ -678,8 +760,11 @@ scan_disk (grub_disk_t disk, struct grub_zfs_data *data, grub_memmove (&(desc.current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); + if (original) + grub_memmove (&(data->current_uberblock), + &ubbest->ubp_uberblock, sizeof (uberblock_t)); - err = check_pool_label (data, &desc, id); + err = check_pool_label (data, &desc); if (err) { grub_errno = GRUB_ERR_NONE; @@ -711,7 +796,6 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) { grub_device_t dev; grub_err_t err; - grub_uint64_t f_id = -1; dev = grub_device_open (name); if (!dev) return 0; @@ -720,7 +804,7 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) grub_device_close (dev); return 0; } - err = scan_disk (dev->disk, data, &f_id); + err = scan_disk (dev, data, 0); if (err == GRUB_ERR_BAD_FS) { grub_device_close (dev); @@ -733,11 +817,6 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) grub_print_error (); return 0; } - if (f_id != id) - { - grub_device_close (dev); - return 0; - } dev_found = dev; return 1; @@ -749,6 +828,36 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) return GRUB_ERR_NONE; } +static grub_err_t +read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, + grub_size_t len, void *buf) +{ + switch (desc->type) + { + case DEVICE_LEAF: + if (!desc->dev) + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + /* read in a data block */ + return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + case DEVICE_MIRROR: + { + grub_err_t err; + unsigned i; + for (i = 0; i < desc->n_children; i++) + { + err = read_device (sector, &desc->children[i], + len, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + return (grub_errno = err); + } + default: + return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); + } +} + static grub_err_t read_dva (const dva_t *dva, grub_zfs_endian_t endian, struct grub_zfs_data *data, @@ -758,18 +867,15 @@ read_dva (const dva_t *dva, unsigned i; grub_err_t err; int try = 0; + offset = dva_get_offset (dva, endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); for (try = 0; try < 1; try++) { for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) - { - /* read in a data block */ - offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - return grub_disk_read (data->devices_attached[i].disk, sector, - 0, len, buf); - } + return read_device (sector, &data->devices_attached[i], + len, buf); err = scan_devices (data, DVA_GET_VDEV (dva)); if (err) return err; @@ -2026,11 +2132,12 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, */ static int -nvlist_find_value (char *nvlist, char *name, int valtype, char **val, +nvlist_find_value (const char *nvlist, const char *name, + int valtype, char **val, grub_size_t *size_out, grub_size_t *nelm_out) { int name_len, type, encode_size; - char *nvpair, *nvp_name; + const char *nvpair, *nvp_name; /* Verify if the 1st and 2nd byte in the nvlist are valid. */ /* NOTE: independently of what endianness header announces all @@ -2072,7 +2179,7 @@ nvlist_find_value (char *nvlist, char *name, int valtype, char **val, if ((grub_strncmp (nvp_name, name, name_len) == 0) && type == valtype) { - *val = nvpair; + *val = (char *) nvpair; *size_out = encode_size; if (nelm_out) *nelm_out = nelm; @@ -2085,7 +2192,8 @@ nvlist_find_value (char *nvlist, char *name, int valtype, char **val, } int -grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) +grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, + grub_uint64_t * out) { char *nvpair; grub_size_t size; @@ -2105,7 +2213,7 @@ grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) } char * -grub_zfs_nvlist_lookup_string (char *nvlist, char *name) +grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name) { char *nvpair; char *ret; @@ -2133,7 +2241,7 @@ grub_zfs_nvlist_lookup_string (char *nvlist, char *name) } char * -grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) +grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) { char *nvpair; char *ret; @@ -2154,7 +2262,8 @@ grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) } int -grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) +grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, + const char *name) { char *nvpair; grub_size_t nelm, size; @@ -2168,9 +2277,9 @@ grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) } static int -get_nvlist_size (char *beg, char *limit) +get_nvlist_size (const char *beg, const char *limit) { - char *ptr; + const char *ptr; grub_uint32_t encode_size; ptr = beg + 8; @@ -2183,7 +2292,7 @@ get_nvlist_size (char *beg, char *limit) } char * -grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, +grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name, grub_size_t index) { char *nvpair, *nvpairptr; @@ -2236,9 +2345,29 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, return ret; } +static void +unmount_device (struct grub_zfs_device_desc *desc) +{ + unsigned i; + switch (desc->type) + { + case DEVICE_LEAF: + if (!desc->original && desc->dev) + grub_device_close (desc->dev); + return; + case DEVICE_MIRROR: + for (i = 0; i < desc->n_children; i++) + unmount_device (&desc->children[i]); + return; + } +} + static void zfs_unmount (struct grub_zfs_data *data) { + unsigned i; + for (i = 0; i < data->n_devices_attached; i++) + unmount_device (&data->devices_attached[i]); grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); @@ -2279,14 +2408,14 @@ zfs_mount (grub_device_t dev) data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) * data->n_devices_allocated); data->n_devices_attached = 0; - err = scan_disk (dev->disk, data, NULL); + err = scan_disk (dev, data, 1); if (err) { zfs_unmount (data); return NULL; } - ub = &(data->devices_attached[0].current_uberblock); + ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC ? LITTLE_ENDIAN : BIG_ENDIAN); diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 057692573..e1759dbbd 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -112,12 +112,14 @@ grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist); grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, grub_uint64_t *mdnobj); -char *grub_zfs_nvlist_lookup_string (char *nvlist, char *name); -char *grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name); -int grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, +char *grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name); +char *grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name); +int grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, grub_uint64_t *out); -char *grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, +char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, + const char *name, grub_size_t index); -int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name); +int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, + const char *name); #endif /* ! GRUB_ZFS_HEADER */ From 925d998e6f9eb04c92465246b6fe458128bafb65 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 07:03:58 +0100 Subject: [PATCH 009/315] Fix a warining --- grub-core/fs/zfs/zfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index b5f25473f..b23490c92 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -843,6 +843,9 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, { grub_err_t err; unsigned i; + if (desc->n_children <= 0) + return grub_error (GRUB_ERR_BAD_FS, + "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { err = read_device (sector, &desc->children[i], From c3b87afcd47d0ad5e4fa8f14c551ce3593c649f4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 20:28:02 +0100 Subject: [PATCH 010/315] Recognize vdev file --- grub-core/fs/zfs/zfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index b23490c92..1dab363b2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -477,7 +477,8 @@ fill_vdev_info_real (const char *nvlist, if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); - if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 + || grub_strcmp (type, VDEV_TYPE_FILE) == 0) { fill->type = DEVICE_LEAF; From 39db1a3f75047d1a665c7d1c194a134b31b1ee0a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 23:46:01 +0100 Subject: [PATCH 011/315] First attempt on RAIDZ. Right now works only with right phase of the moon. --- grub-core/fs/zfs/zfs.c | 122 +++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1dab363b2..23e9c7b36 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -140,7 +140,7 @@ typedef struct dnode_end struct grub_zfs_device_desc { - enum { DEVICE_LEAF, DEVICE_MIRROR } type; + enum { DEVICE_LEAF, DEVICE_MIRROR, DEVICE_RAIDZ } type; grub_uint64_t id; grub_uint64_t guid; @@ -148,6 +148,9 @@ struct grub_zfs_device_desc unsigned n_children; struct grub_zfs_device_desc *children; + /* Valid only for RAIDZ. */ + unsigned nparity; + /* Valid only for leaf devices. */ grub_device_t dev; grub_disk_addr_t vdev_phys_sector; @@ -290,13 +293,13 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, || (actual_cksum.zc_word[2] != zc.zc_word[2]) || (actual_cksum.zc_word[3] != zc.zc_word[3])) { - grub_dprintf ("zfs", "checksum %d verification failed\n", checksum); - grub_dprintf ("zfs", "actual checksum %16llx %16llx %16llx %16llx\n", + grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name); + grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n", (unsigned long long) actual_cksum.zc_word[0], (unsigned long long) actual_cksum.zc_word[1], (unsigned long long) actual_cksum.zc_word[2], (unsigned long long) actual_cksum.zc_word[3]); - grub_dprintf ("zfs", "expected checksum %16llx %16llx %16llx %16llx\n", + grub_dprintf ("zfs", "expected checksum %016llx %016llx %016llx %016llx\n", (unsigned long long) zc.zc_word[0], (unsigned long long) zc.zc_word[1], (unsigned long long) zc.zc_word[2], @@ -493,21 +496,34 @@ fill_vdev_info_real (const char *nvlist, return GRUB_ERR_NONE; } - if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0 + || grub_strcmp (type, VDEV_TYPE_RAIDZ) == 0) { int nelm, i; - fill->type = DEVICE_MIRROR; + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + fill->type = DEVICE_MIRROR; + else + { + grub_uint64_t par; + fill->type = DEVICE_RAIDZ; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + fill->nparity = par; + } nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); if (nelm <= 0) return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); - fill->n_children = nelm; - - fill->children = grub_zalloc (fill->n_children - * sizeof (fill->children[0])); + if (!fill->children) + { + fill->n_children = nelm; + + fill->children = grub_zalloc (fill->n_children + * sizeof (fill->children[0])); + } for (i = 0; i < nelm; i++) { @@ -789,9 +805,8 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, } static grub_err_t -scan_devices (struct grub_zfs_data *data, grub_uint64_t id) +scan_devices (struct grub_zfs_data *data) { - grub_device_t dev_found = NULL; auto int hook (const char *name); int hook (const char *name) { @@ -819,27 +834,29 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) return 0; } - dev_found = dev; - return 1; + return 0; } grub_device_iterate (hook); - if (!dev_found) - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find device 0x%" PRIxGRUB_UINT64_T, id); return GRUB_ERR_NONE; } static grub_err_t -read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, +read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) { switch (desc->type) { case DEVICE_LEAF: - if (!desc->dev) - return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); - /* read in a data block */ - return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + { + grub_uint64_t sector; + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + if (!desc->dev) + { + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + } + /* read in a data block */ + return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + } case DEVICE_MIRROR: { grub_err_t err; @@ -849,7 +866,7 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (sector, &desc->children[i], + err = read_device (offset, &desc->children[i], len, buf); if (!err) break; @@ -857,9 +874,41 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, } return (grub_errno = err); } - default: - return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); + case DEVICE_RAIDZ: + { + grub_uint64_t sector; + grub_uint64_t high; + grub_uint32_t devn; + if (desc->n_children <= 0) + return grub_error (GRUB_ERR_BAD_FS, + "non-positive number of mirror children"); + offset += 512; + + sector = offset >> 9; + high = grub_divmod64 (sector, desc->n_children, &devn); + + while (len > 0) + { + grub_size_t csize; + grub_err_t err; + + csize = 0x200 * desc->n_children - (offset & 0x1ff); + if (csize > len) + csize = len; + + err = read_device (high << 9, &desc->children[devn], + csize, buf); + if (err) + return err; + len -= csize; + buf = (grub_uint8_t *) buf + csize; + devn = (devn + 1) % desc->n_children; + high++; + } + } + return GRUB_ERR_NONE; } + return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } static grub_err_t @@ -867,26 +916,30 @@ read_dva (const dva_t *dva, grub_zfs_endian_t endian, struct grub_zfs_data *data, void *buf, grub_size_t len) { - grub_uint64_t offset, sector; + grub_uint64_t offset; unsigned i; grub_err_t err; int try = 0; offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - for (try = 0; try < 1; try++) + for (try = 0; try < 2; try++) { for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) - return read_device (sector, &data->devices_attached[i], - len, buf); - err = scan_devices (data, DVA_GET_VDEV (dva)); + { + err = read_device (offset, &data->devices_attached[i], + len, buf); + if (!err) + return GRUB_ERR_NONE; + break; + } + if (try == 1) + break; + err = scan_devices (data); if (err) return err; } - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find device 0x%" PRIxGRUB_UINT64_T, - DVA_GET_VDEV (dva)); + return err; } /* @@ -2359,6 +2412,7 @@ unmount_device (struct grub_zfs_device_desc *desc) if (!desc->original && desc->dev) grub_device_close (desc->dev); return; + case DEVICE_RAIDZ: case DEVICE_MIRROR: for (i = 0; i < desc->n_children; i++) unmount_device (&desc->children[i]); From bfff320cdfd27c197dec74cdff9c258098acadb3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 7 Dec 2010 11:45:37 +0100 Subject: [PATCH 012/315] Apparently functioning raidz. Still mostly a guesswork so may break --- grub-core/fs/zfs/zfs.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 23e9c7b36..e41067c38 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -842,7 +842,7 @@ scan_devices (struct grub_zfs_data *data) static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - grub_size_t len, void *buf) + grub_uint32_t asize, grub_size_t len, void *buf) { switch (desc->type) { @@ -866,7 +866,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (offset, &desc->children[i], + err = read_device (offset, &desc->children[i], asize, len, buf); if (!err) break; @@ -877,35 +877,35 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, case DEVICE_RAIDZ: { grub_uint64_t sector; - grub_uint64_t high; - grub_uint32_t devn; - if (desc->n_children <= 0) - return grub_error (GRUB_ERR_BAD_FS, - "non-positive number of mirror children"); - offset += 512; + grub_uint32_t bsize; + unsigned c = 0; + bsize = (asize + desc->nparity) / desc->n_children; sector = offset >> 9; - high = grub_divmod64 (sector, desc->n_children, &devn); - while (len > 0) { grub_size_t csize; + grub_uint64_t high; + grub_uint32_t devn; grub_err_t err; - - csize = 0x200 * desc->n_children - (offset & 0x1ff); + high = grub_divmod64 (sector + (asize > 2) + c, desc->n_children, + &devn); + csize = bsize << 9; if (csize > len) csize = len; - + grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T + "+%d+%u -> (0x%" PRIxGRUB_UINT64_T ", 0x%x)\n", + sector,(asize > 2), c, high, devn); err = read_device (high << 9, &desc->children[devn], - csize, buf); + bsize, csize, buf); if (err) return err; + c++; + buf = (char *) buf + csize; len -= csize; - buf = (grub_uint8_t *) buf + csize; - devn = (devn + 1) % desc->n_children; - high++; } - } + return GRUB_ERR_NONE; + } return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); @@ -928,7 +928,7 @@ read_dva (const dva_t *dva, if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) { err = read_device (offset, &data->devices_attached[i], - len, buf); + dva->dva_word[0] & 0xffffff, len, buf); if (!err) return GRUB_ERR_NONE; break; From eb03b5527161d9537e914870858d232e1fa277a9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 14:56:02 +0100 Subject: [PATCH 013/315] fix ZFS label handling in non-single disk configs --- grub-core/fs/zfs/zfs.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index e41067c38..cafe915c5 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -179,6 +179,7 @@ struct grub_zfs_data struct grub_zfs_device_desc *devices_attached; unsigned n_devices_attached; unsigned n_devices_allocated; + struct grub_zfs_device_desc *device_original; uberblock_t current_uberblock; @@ -463,7 +464,8 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) } static grub_err_t -fill_vdev_info_real (const char *nvlist, +fill_vdev_info_real (struct grub_zfs_data *data, + const char *nvlist, struct grub_zfs_device_desc *fill, struct grub_zfs_device_desc *insert) { @@ -492,6 +494,8 @@ fill_vdev_info_real (const char *nvlist, fill->current_uberblock = insert->current_uberblock; fill->original = insert->original; } + if (!data->device_original) + data->device_original = fill; return GRUB_ERR_NONE; } @@ -533,7 +537,7 @@ fill_vdev_info_real (const char *nvlist, child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); - err = fill_vdev_info_real (child, &fill->children[i], insert); + err = fill_vdev_info_real (data, child, &fill->children[i], insert); grub_free (child); @@ -559,7 +563,7 @@ fill_vdev_info (struct grub_zfs_data *data, for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == id) - return fill_vdev_info_real (nvlist, &data->devices_attached[i], + return fill_vdev_info_real (data, nvlist, &data->devices_attached[i], diskdesc); data->n_devices_attached++; @@ -581,7 +585,7 @@ fill_vdev_info (struct grub_zfs_data *data, grub_memset (&data->devices_attached[data->n_devices_attached - 1], 0, sizeof (data->devices_attached[data->n_devices_attached - 1])); - return fill_vdev_info_real (nvlist, + return fill_vdev_info_real (data, nvlist, &data->devices_attached[data->n_devices_attached - 1], diskdesc); } @@ -2514,7 +2518,7 @@ grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) zfs = zfs_mount (dev); if (!zfs) return grub_errno; - err = zfs_fetch_nvlist (&zfs->devices_attached[0], nvlist); + err = zfs_fetch_nvlist (zfs->device_original, nvlist); zfs_unmount (zfs); return err; } @@ -2530,7 +2534,7 @@ zfs_label (grub_device_t device, char **label) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data->devices_attached, &nvlist); + err = zfs_fetch_nvlist (data->device_original, &nvlist); if (err) { zfs_unmount (data); From ea0df4e9530965c4ec04982656f27e074aeefac8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 15:01:33 +0100 Subject: [PATCH 014/315] ZFS mtime support --- grub-core/fs/zfs/zfs.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index cafe915c5..327e99a90 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -2565,6 +2565,29 @@ zfs_uuid (grub_device_t device, char **uuid) return GRUB_ERR_NONE; } +static grub_err_t +zfs_mtime (grub_device_t device, grub_int32_t *mt) +{ + struct grub_zfs_data *data; + grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + uberblock_t *ub; + + *mt = 0; + + data = zfs_mount (device); + if (! data) + return grub_errno; + + ub = &(data->current_uberblock); + ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, + LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? LITTLE_ENDIAN : BIG_ENDIAN); + + *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian); + zfs_unmount (data); + return GRUB_ERR_NONE; +} + /* * zfs_open() locates a file in the rootpool by following the * MOS and places the dnode of the file in the memory address DNODE. @@ -2934,7 +2957,7 @@ static struct grub_fs grub_zfs_fs = { .close = grub_zfs_close, .label = zfs_label, .uuid = zfs_uuid, - .mtime = 0, + .mtime = zfs_mtime, .next = 0 }; From 70e8145a7b52759fcf94fe16fa3ea287d83eb904 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 16:10:26 +0100 Subject: [PATCH 015/315] Plan9 support --- grub-core/Makefile.core.def | 7 + grub-core/loader/i386/pc/plan9.c | 219 +++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 grub-core/loader/i386/pc/plan9.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..ae604b3c6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1146,6 +1146,13 @@ module = { enable = x86; }; +module = { + name = plan9; + i386_pc = loader/i386/pc/plan9.c; + enable = i386_pc; +}; + + module = { name = linux16; i386_pc = loader/i386/pc/linux.c; diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c new file mode 100644 index 000000000..aa96ae83c --- /dev/null +++ b/grub-core/loader/i386/pc/plan9.c @@ -0,0 +1,219 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; +static struct grub_relocator *rel; +static grub_uint32_t eip = 0xffffffff; + +#define GRUB_PLAN9_TARGET 0x100000 +#define GRUB_PLAN9_CONFIG_ADDR 0x001200 +#define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 +#define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" + +struct grub_plan9_header +{ + grub_uint32_t magic; +#define GRUB_PLAN9_MAGIC 0x1eb + grub_uint32_t text_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t zero1; + grub_uint32_t entry_addr; + grub_uint32_t zero2; + grub_uint32_t zero3; +}; + +static grub_err_t +grub_plan9_boot (void) +{ + struct grub_relocator32_state state = { + .eax = 0, + .eip = eip, + .ebx = 0, + .ecx = 0, + .edx = 0, + .edi = 0, + .esp = 0, + .ebp = 0, + .esi = 0 + /* grub_uint32_t ebp; + grub_uint32_t esi; +*/ + }; + grub_video_set_mode ("text", 0, 0); + + return grub_relocator32_boot (rel, state); +} + +static grub_err_t +grub_plan9_unload (void) +{ + grub_relocator_unload (rel); + rel = NULL; + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_err_t err; + void *mem; + grub_uint8_t *ptr; + grub_size_t memsize, padsize; + struct grub_plan9_header hdr; + char *config, *configptr; + grub_size_t configsize; + int i; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + + grub_dl_ref (my_mod); + + rel = grub_relocator_new (); + if (!rel) + goto fail; + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) + goto fail; + + if (grub_be_to_cpu32 (hdr.magic) != GRUB_PLAN9_MAGIC + || hdr.zero1 || hdr.zero2 || hdr.zero3) + { + grub_error (GRUB_ERR_BAD_OS, "unsupported Plan9"); + goto fail; + } + + memsize = sizeof (hdr); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16); + memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16); + eip = grub_be_to_cpu32 (hdr.entry_addr) & 0xfffffff; + + /* path */ + configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; + /* magic */ + configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + for (i = 1; i < argc; i++) + configsize += grub_strlen (argv[i]) + 1; + /* Terminating \0. */ + configsize++; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR, + configsize); + if (err) + goto fail; + config = get_virtual_current_address (ch); + } + + grub_memset (config, 0, GRUB_PLAN9_CONFIG_PATH_SIZE); + configptr = config + GRUB_PLAN9_CONFIG_PATH_SIZE; + grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, + sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); + configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + for (i = 1; i < argc; i++) + { + configptr = grub_stpcpy (configptr, argv[i]); + *configptr++ = '\n'; + } + *configptr = 0; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET, + memsize); + if (err) + goto fail; + mem = get_virtual_current_address (ch); + } + + ptr = mem; + grub_memcpy (ptr, &hdr, sizeof (hdr)); + ptr += sizeof (hdr); + + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16) + - grub_be_to_cpu32 (hdr.text_size); + + grub_memset (ptr, 0, padsize); + ptr += padsize; + + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.data_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16) + - grub_be_to_cpu32 (hdr.data_size); + + grub_memset (ptr, 0, padsize); + ptr += padsize; + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16)); + + grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); + return GRUB_ERR_NONE; + + fail: + + if (file) + grub_file_close (file); + + grub_plan9_unload (); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(plan9) +{ + cmd = grub_register_command ("plan9", grub_cmd_plan9, + 0, N_("Load Plan9 kernel.")); + my_mod = mod; +} + +GRUB_MOD_FINI(plan9) +{ + grub_unregister_command (cmd); +} From 239ab5f0480cb232ccb987856f21d4875629702e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 17:02:25 +0100 Subject: [PATCH 016/315] Fix Plan9 alignment --- grub-core/loader/i386/pc/plan9.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index aa96ae83c..aaceb2825 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -36,6 +36,7 @@ static struct grub_relocator *rel; static grub_uint32_t eip = 0xffffffff; #define GRUB_PLAN9_TARGET 0x100000 +#define GRUB_PLAN9_ALIGN 4096 #define GRUB_PLAN9_CONFIG_ADDR 0x001200 #define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 #define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" @@ -121,10 +122,10 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), goto fail; } - memsize = sizeof (hdr); - memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16); - memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16); - memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16); + memsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN); + memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN); eip = grub_be_to_cpu32 (hdr.entry_addr) & 0xfffffff; /* path */ @@ -174,8 +175,9 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) goto fail; ptr += grub_be_to_cpu32 (hdr.text_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16) - - grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) + - sizeof (hdr); grub_memset (ptr, 0, padsize); ptr += padsize; @@ -184,12 +186,12 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) goto fail; ptr += grub_be_to_cpu32 (hdr.data_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16) + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.data_size); grub_memset (ptr, 0, padsize); ptr += padsize; - grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16)); + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN)); grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); return GRUB_ERR_NONE; From 3c50773923e086199748c7d431c2d0c1fd419bbd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 20:51:32 +0100 Subject: [PATCH 017/315] Ignore fields zero1 and zero3 --- grub-core/loader/i386/pc/plan9.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index aaceb2825..7b777d0b3 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -48,10 +48,10 @@ struct grub_plan9_header grub_uint32_t text_size; grub_uint32_t data_size; grub_uint32_t bss_size; - grub_uint32_t zero1; + grub_uint32_t sectiona; grub_uint32_t entry_addr; - grub_uint32_t zero2; - grub_uint32_t zero3; + grub_uint32_t zero; + grub_uint32_t sectionb; }; static grub_err_t @@ -116,7 +116,7 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), goto fail; if (grub_be_to_cpu32 (hdr.magic) != GRUB_PLAN9_MAGIC - || hdr.zero1 || hdr.zero2 || hdr.zero3) + || hdr.zero) { grub_error (GRUB_ERR_BAD_OS, "unsupported Plan9"); goto fail; From ac9ef7eef97d4c217a849e185ca5e06c560b9c83 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Dec 2010 01:18:21 +0100 Subject: [PATCH 018/315] plan9 subpartition support --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 ++ grub-core/partmap/plan.c | 118 ++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 grub-core/partmap/plan.c diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..2b9d28cf0 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -91,6 +91,7 @@ library = { common = grub-core/partmap/gpt.c; common = grub-core/partmap/msdos.c; common = grub-core/partmap/sun.c; + common = grub-core/partmap/plan.c; common = grub-core/partmap/sunpc.c; common = grub-core/partmap/bsdlabel.c; common = grub-core/script/function.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ae604b3c6..9151e434b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1308,6 +1308,11 @@ module = { common = partmap/sun.c; }; +module = { + name = part_plan; + common = partmap/plan.c; +}; + module = { name = part_bsd; common = partmap/bsdlabel.c; diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c new file mode 100644 index 000000000..c62d04b73 --- /dev/null +++ b/grub-core/partmap/plan.c @@ -0,0 +1,118 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct grub_partition_map grub_plan_partition_map; + +static grub_err_t +plan_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition p; + int ptr = 0; + grub_err_t err; + + p.partmap = &grub_plan_partition_map; + p.msdostype = 0; + + for (p.number = 0; ; p.number++) + { + char sig[sizeof ("part ") - 1]; + char c; + + p.offset = (ptr >> GRUB_DISK_SECTOR_BITS) + 1; + p.index = ptr & (GRUB_DISK_SECTOR_SIZE - 1); + + err = grub_disk_read (disk, 1, ptr, sizeof (sig), sig); + if (err) + return err; + if (grub_memcmp (sig, "part ", sizeof ("part ") - 1) != 0) + break; + ptr += sizeof (sig); + do + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + } + while (grub_isdigit (c) || grub_isalpha (c)); + if (c != ' ') + break; + p.start = 0; + while (1) + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + if (!grub_isdigit (c)) + break; + p.start = p.start * 10 + (c - '0'); + } + if (c != ' ') + break; + p.len = 0; + while (1) + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + if (!grub_isdigit (c)) + break; + p.len = p.len * 10 + (c - '0'); + } + if (c != '\n') + break; + p.len -= p.start; + if (hook (disk, &p)) + return grub_errno; + } + if (p.number == 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a plan partition table"); + + return GRUB_ERR_NONE; +} + +/* Partition map type. */ +static struct grub_partition_map grub_plan_partition_map = + { + .name = "plan", + .iterate = plan_partition_map_iterate, + }; + +GRUB_MOD_INIT(part_plan) +{ + grub_partition_map_register (&grub_plan_partition_map); +} + +GRUB_MOD_FINI(part_plan) +{ + grub_partition_map_unregister (&grub_plan_partition_map); +} + From da94d203d9f421259aca4548d9862d138c5d7188 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:04:31 +0100 Subject: [PATCH 019/315] Generate partmaps for plan9 --- grub-core/loader/i386/pc/plan9.c | 279 +++++++++++++++++++++++++++---- include/grub/disk.h | 2 - include/grub/misc.h | 1 + include/grub/mm.h | 17 ++ include/grub/msdos_partition.h | 2 + 5 files changed, 271 insertions(+), 30 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 7b777d0b3..2418bf1a1 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -67,9 +69,6 @@ grub_plan9_boot (void) .esp = 0, .ebp = 0, .esi = 0 - /* grub_uint32_t ebp; - grub_uint32_t esi; -*/ }; grub_video_set_mode ("text", 0, 0); @@ -90,14 +89,218 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; - grub_err_t err; void *mem; - grub_uint8_t *ptr; grub_size_t memsize, padsize; struct grub_plan9_header hdr; char *config, *configptr; grub_size_t configsize; int i; + char *pmap = NULL; + grub_size_t pmapalloc = 256; + grub_size_t pmapptr = 0; + int noslash = 1; + char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; + int prefixescnt[5]; + + auto int fill_partition (grub_disk_t disk, + const grub_partition_t partition); + int fill_partition (grub_disk_t disk, + const grub_partition_t partition) + { + if (!noslash) + { + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + pmap[pmapptr++] = '/'; + } + noslash = 0; + + if (grub_strcmp (partition->partmap->name, "plan") == 0) + { + unsigned ptr = partition->index + sizeof ("part ") - 1; + grub_err_t err; + disk->partition = partition->parent; + do + { + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr); + if (err) + { + disk->partition = 0; + return err; + } + ptr++; + pmapptr++; + } + while (grub_isalpha (pmap[pmapptr - 1]) + || grub_isdigit (pmap[pmapptr - 1])); + pmapptr--; + } + else + { + char name[50]; + int c = 0; + if (grub_strcmp (partition->partmap->name, "msdos") == 0) + { + switch (partition->msdostype) + { + case GRUB_PC_PARTITION_TYPE_PLAN9: + c = 1; + break; + case GRUB_PC_PARTITION_TYPE_NTFS: + c = 2; + break; + case GRUB_PC_PARTITION_TYPE_MINIX: + case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: + case GRUB_PC_PARTITION_TYPE_EXT2FS: + c = 3; + break; + case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: + c = 4; + break; + } + } + + if (prefixescnt[c] == 0) + grub_strcpy (name, prefixes[c]); + else + grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], + prefixescnt[c]); + prefixescnt[c]++; + if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1, + &pmapalloc, (void **) &pmap)) + return 1; + grub_strcpy (pmap + pmapptr, name); + pmapptr += grub_strlen (name); + } + if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, + (void **) &pmap)) + return 1; + pmap[pmapptr++] = ' '; + grub_snprintf (pmap + pmapptr, 25 + 5 + 25, + "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, + grub_partition_get_start (partition), + grub_partition_get_start (partition) + + grub_partition_get_len (partition)); + pmapptr += grub_strlen (pmap + pmapptr); + return 0; + } + + auto int fill_disk (const char *name); + int fill_disk (const char *name) + { + grub_device_t dev; + int file_disk; + char *plan9name = NULL; + + dev = grub_device_open (name); + if (!dev) + { + grub_print_error (); + return 0; + } + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + file_disk = file->device->disk && dev->disk->id == file->device->disk->id + && dev->disk->dev->id == file->device->disk->dev->id; + switch (dev->disk->dev->id) + { + case GRUB_DISK_DEVICE_BIOSDISK_ID: + if (dev->disk->id & 0x80) + plan9name = grub_xasprintf ("sdB%u", + (unsigned) (dev->disk->id & 0x7f)); + else + plan9name = grub_xasprintf ("fd%u", + (unsigned) (dev->disk->id & 0x7f)); + break; + /* Shouldn't happen as Plan9 doesn't work on these platforms. */ + case GRUB_DISK_DEVICE_OFDISK_ID: + case GRUB_DISK_DEVICE_EFIDISK_ID: + + /* Plan9 doesn't see those. */ + case GRUB_DISK_DEVICE_LOOPBACK_ID: + case GRUB_DISK_DEVICE_RAID_ID: + case GRUB_DISK_DEVICE_LVM_ID: + case GRUB_DISK_DEVICE_HOST_ID: + case GRUB_DISK_DEVICE_MEMDISK_ID: + case GRUB_DISK_DEVICE_LUKS_ID: + + /* Not sure how to handle those. */ + case GRUB_DISK_DEVICE_PXE_ID: + case GRUB_DISK_DEVICE_NAND_ID: + if (!file_disk) + { + grub_device_close (dev); + return 0; + } + + /* if it's the disk the kernel is loaded from we need to name + it nevertheless. */ + plan9name = grub_strdup ("sdZ0"); + break; + + case GRUB_DISK_DEVICE_ATA_ID: + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + } + break; + case GRUB_DISK_DEVICE_SCSI_ID: + if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) + == GRUB_SCSI_SUBSYSTEM_ATAPI) + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + break; + } + + /* FIXME: how does Plan9 number controllers? + We probably need save the SCSI devices and sort them */ + plan9name + = grub_xasprintf ("sd0%u", (unsigned) + ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) & 0xf)); + break; + } + if (!plan9name) + { + grub_print_error (); + return 0; + } + if (grub_extend_alloc (pmapptr + grub_strlen (plan9name) + + sizeof ("part="), &pmapalloc, + (void **) &pmap)) + { + grub_free (plan9name); + return 1; + } + grub_strcpy (pmap + pmapptr, plan9name); + pmapptr += grub_strlen (plan9name); + grub_free (plan9name); + grub_strcpy (pmap + pmapptr, "part="); + pmapptr += sizeof ("part=") - 1; + + noslash = 1; + grub_memset (prefixescnt, 0, sizeof (prefixescnt)); + if (grub_partition_iterate (dev->disk, fill_partition)) + return 1; + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + pmap[pmapptr++] = '\n'; + + return 0; + } if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); @@ -112,6 +315,18 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), if (! file) goto fail; + pmap = grub_malloc (pmapalloc); + if (!pmap) + goto fail; + + if (grub_disk_dev_iterate (fill_disk)) + goto fail; + + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, + (void **) &pmap)) + goto fail; + pmap[pmapptr] = 0; + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) goto fail; @@ -134,11 +349,13 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; for (i = 1; i < argc; i++) configsize += grub_strlen (argv[i]) + 1; + configsize += pmapptr; /* Terminating \0. */ configsize++; { grub_relocator_chunk_t ch; + grub_err_t err; err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR, configsize); if (err) @@ -156,10 +373,12 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configptr = grub_stpcpy (configptr, argv[i]); *configptr++ = '\n'; } - *configptr = 0; + configptr = grub_stpcpy (configptr, pmap); { grub_relocator_chunk_t ch; + grub_err_t err; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET, memsize); if (err) @@ -167,36 +386,40 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), mem = get_virtual_current_address (ch); } - ptr = mem; - grub_memcpy (ptr, &hdr, sizeof (hdr)); - ptr += sizeof (hdr); + { + grub_uint8_t *ptr; + ptr = mem; + grub_memcpy (ptr, &hdr, sizeof (hdr)); + ptr += sizeof (hdr); - if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) - goto fail; - ptr += grub_be_to_cpu32 (hdr.text_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), - GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) - - sizeof (hdr); + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) + - sizeof (hdr); - grub_memset (ptr, 0, padsize); - ptr += padsize; + grub_memset (ptr, 0, padsize); + ptr += padsize; - if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) - goto fail; - ptr += grub_be_to_cpu32 (hdr.data_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) - - grub_be_to_cpu32 (hdr.data_size); - - grub_memset (ptr, 0, padsize); - ptr += padsize; - grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN)); + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.data_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) + - grub_be_to_cpu32 (hdr.data_size); + grub_memset (ptr, 0, padsize); + ptr += padsize; + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), + GRUB_PLAN9_ALIGN)); + } grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); return GRUB_ERR_NONE; fail: + grub_free (pmap); if (file) grub_file_close (file); diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..b72b26f46 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -38,10 +38,8 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_ATA_ID, GRUB_DISK_DEVICE_MEMDISK_ID, GRUB_DISK_DEVICE_NAND_ID, - GRUB_DISK_DEVICE_UUID_ID, GRUB_DISK_DEVICE_PXE_ID, GRUB_DISK_DEVICE_SCSI_ID, - GRUB_DISK_DEVICE_FILE_ID, GRUB_DISK_DEVICE_LUKS_ID }; diff --git a/include/grub/misc.h b/include/grub/misc.h index 6fcaa148b..b26a70cd0 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -353,4 +353,5 @@ extern int EXPORT_VAR(grub_no_autoload); #define grub_no_autoload 0 #endif + #endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/mm.h b/include/grub/mm.h index cc115907a..5810fff41 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -72,4 +72,21 @@ void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line, grub_size_t align, grub_size_t size); #endif /* MM_DEBUG && ! GRUB_UTIL */ +#include + +static inline grub_err_t +grub_extend_alloc (grub_size_t sz, grub_size_t *allocated, void **ptr) +{ + void *n; + if (sz < *allocated) + return GRUB_ERR_NONE; + + *allocated = 2 * sz; + n = grub_realloc (*ptr, *allocated); + if (!n) + return grub_errno; + *ptr = n; + return GRUB_ERR_NONE; +} + #endif /* ! GRUB_MM_H */ diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h index a6e3fda49..9c8ac3e8a 100644 --- a/include/grub/msdos_partition.h +++ b/include/grub/msdos_partition.h @@ -42,9 +42,11 @@ #define GRUB_PC_PARTITION_TYPE_FAT32_LBA 0xc #define GRUB_PC_PARTITION_TYPE_FAT16_LBA 0xe #define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED 0xf +#define GRUB_PC_PARTITION_TYPE_PLAN9 0x39 #define GRUB_PC_PARTITION_TYPE_EZD 0x55 #define GRUB_PC_PARTITION_TYPE_MINIX 0x80 #define GRUB_PC_PARTITION_TYPE_LINUX_MINIX 0x81 +#define GRUB_PC_PARTITION_TYPE_LINUX_SWAP 0x82 #define GRUB_PC_PARTITION_TYPE_EXT2FS 0x83 #define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED 0x85 #define GRUB_PC_PARTITION_TYPE_VSTAFS 0x9e From 645b8cd99f6a83df1c0780b0bfdf8685cd21adb9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:22:11 +0100 Subject: [PATCH 020/315] Allow override Plan9 device names --- grub-core/loader/i386/pc/plan9.c | 161 ++++++++++++++++++------------- 1 file changed, 93 insertions(+), 68 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 2418bf1a1..228ea6159 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -32,6 +32,7 @@ #include #include #include +#include static grub_dl_t my_mod; static struct grub_relocator *rel; @@ -43,6 +44,14 @@ static grub_uint32_t eip = 0xffffffff; #define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 #define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" +static const struct grub_arg_option options[] = + { + {"map", 'm', GRUB_ARG_OPTION_REPEATABLE, + N_("Override guessed mapping of Plan9 devices."), "GRUBDEVICE=PLAN9DEVICE", + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + struct grub_plan9_header { grub_uint32_t magic; @@ -85,8 +94,7 @@ grub_plan9_unload (void) } static grub_err_t -grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) +grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) { grub_file_t file = 0; void *mem; @@ -94,7 +102,6 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), struct grub_plan9_header hdr; char *config, *configptr; grub_size_t configsize; - int i; char *pmap = NULL; grub_size_t pmapalloc = 256; grub_size_t pmapptr = 0; @@ -193,6 +200,7 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), grub_device_t dev; int file_disk; char *plan9name = NULL; + unsigned i; dev = grub_device_open (name); if (!dev) @@ -207,55 +215,50 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), } file_disk = file->device->disk && dev->disk->id == file->device->disk->id && dev->disk->dev->id == file->device->disk->dev->id; - switch (dev->disk->dev->id) - { - case GRUB_DISK_DEVICE_BIOSDISK_ID: - if (dev->disk->id & 0x80) - plan9name = grub_xasprintf ("sdB%u", - (unsigned) (dev->disk->id & 0x7f)); - else - plan9name = grub_xasprintf ("fd%u", - (unsigned) (dev->disk->id & 0x7f)); + for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++) + if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0 + && ctxt->state[0].args[i][grub_strlen (name)] == '=') break; - /* Shouldn't happen as Plan9 doesn't work on these platforms. */ - case GRUB_DISK_DEVICE_OFDISK_ID: - case GRUB_DISK_DEVICE_EFIDISK_ID: - - /* Plan9 doesn't see those. */ - case GRUB_DISK_DEVICE_LOOPBACK_ID: - case GRUB_DISK_DEVICE_RAID_ID: - case GRUB_DISK_DEVICE_LVM_ID: - case GRUB_DISK_DEVICE_HOST_ID: - case GRUB_DISK_DEVICE_MEMDISK_ID: - case GRUB_DISK_DEVICE_LUKS_ID: - - /* Not sure how to handle those. */ - case GRUB_DISK_DEVICE_PXE_ID: - case GRUB_DISK_DEVICE_NAND_ID: - if (!file_disk) - { - grub_device_close (dev); - return 0; - } - - /* if it's the disk the kernel is loaded from we need to name - it nevertheless. */ - plan9name = grub_strdup ("sdZ0"); - break; - - case GRUB_DISK_DEVICE_ATA_ID: + if (ctxt->state[0].args && ctxt->state[0].args[i]) + plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1); + else + switch (dev->disk->dev->id) { - int unit; - if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) - unit = 0; + case GRUB_DISK_DEVICE_BIOSDISK_ID: + if (dev->disk->id & 0x80) + plan9name = grub_xasprintf ("sdB%u", + (unsigned) (dev->disk->id & 0x7f)); else - unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); - plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - } - break; - case GRUB_DISK_DEVICE_SCSI_ID: - if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) - == GRUB_SCSI_SUBSYSTEM_ATAPI) + plan9name = grub_xasprintf ("fd%u", + (unsigned) (dev->disk->id & 0x7f)); + break; + /* Shouldn't happen as Plan9 doesn't work on these platforms. */ + case GRUB_DISK_DEVICE_OFDISK_ID: + case GRUB_DISK_DEVICE_EFIDISK_ID: + + /* Plan9 doesn't see those. */ + case GRUB_DISK_DEVICE_LOOPBACK_ID: + case GRUB_DISK_DEVICE_RAID_ID: + case GRUB_DISK_DEVICE_LVM_ID: + case GRUB_DISK_DEVICE_HOST_ID: + case GRUB_DISK_DEVICE_MEMDISK_ID: + case GRUB_DISK_DEVICE_LUKS_ID: + + /* Not sure how to handle those. */ + case GRUB_DISK_DEVICE_PXE_ID: + case GRUB_DISK_DEVICE_NAND_ID: + if (!file_disk) + { + grub_device_close (dev); + return 0; + } + + /* if it's the disk the kernel is loaded from we need to name + it nevertheless. */ + plan9name = grub_strdup ("sdZ0"); + break; + + case GRUB_DISK_DEVICE_ATA_ID: { int unit; if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) @@ -263,16 +266,30 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), else unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - break; } + break; + case GRUB_DISK_DEVICE_SCSI_ID: + if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) + == GRUB_SCSI_SUBSYSTEM_ATAPI) + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, + 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + break; + } - /* FIXME: how does Plan9 number controllers? - We probably need save the SCSI devices and sort them */ - plan9name - = grub_xasprintf ("sd0%u", (unsigned) - ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) & 0xf)); - break; - } + /* FIXME: how does Plan9 number controllers? + We probably need save the SCSI devices and sort them */ + plan9name + = grub_xasprintf ("sd0%u", (unsigned) + ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) + & 0xf)); + break; + } if (!plan9name) { grub_print_error (); @@ -347,8 +364,11 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; /* magic */ configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - for (i = 1; i < argc; i++) - configsize += grub_strlen (argv[i]) + 1; + { + int i; + for (i = 1; i < argc; i++) + configsize += grub_strlen (argv[i]) + 1; + } configsize += pmapptr; /* Terminating \0. */ configsize++; @@ -368,11 +388,14 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - for (i = 1; i < argc; i++) - { - configptr = grub_stpcpy (configptr, argv[i]); - *configptr++ = '\n'; - } + { + int i; + for (i = 1; i < argc; i++) + { + configptr = grub_stpcpy (configptr, argv[i]); + *configptr++ = '\n'; + } + } configptr = grub_stpcpy (configptr, pmap); { @@ -429,16 +452,18 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(plan9) { - cmd = grub_register_command ("plan9", grub_cmd_plan9, - 0, N_("Load Plan9 kernel.")); + cmd = grub_register_extcmd ("plan9", grub_cmd_plan9, + GRUB_COMMAND_OPTIONS_AT_START, + N_("KERNEL ARGS"), N_("Load Plan9 kernel."), + options); my_mod = mod; } GRUB_MOD_FINI(plan9) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } From 5c61fc9f48fee403037fc4399832f8c96d789f6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:37:03 +0100 Subject: [PATCH 021/315] supply boot file to plan9 --- grub-core/loader/i386/pc/plan9.c | 54 ++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 228ea6159..02d1d63cd 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -108,12 +108,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) int noslash = 1; char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; int prefixescnt[5]; + char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL; auto int fill_partition (grub_disk_t disk, const grub_partition_t partition); int fill_partition (grub_disk_t disk, const grub_partition_t partition) { + int file_disk = 0; + int pstart, pend; if (!noslash) { if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) @@ -122,6 +125,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } noslash = 0; + file_disk = file->device->disk && disk->id == file->device->disk->id + && disk->dev->id == file->device->disk->dev->id; + + pstart = pmapptr; if (grub_strcmp (partition->partmap->name, "plan") == 0) { unsigned ptr = partition->index + sizeof ("part ") - 1; @@ -180,7 +187,8 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) return 1; grub_strcpy (pmap + pmapptr, name); pmapptr += grub_strlen (name); - } + } + pend = pmapptr; if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, (void **) &pmap)) return 1; @@ -190,6 +198,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) grub_partition_get_start (partition), grub_partition_get_start (partition) + grub_partition_get_len (partition)); + if (file_disk && grub_partition_get_start (partition) + == grub_partition_get_start (file->device->disk->partition) + && grub_partition_get_len (partition) + == grub_partition_get_len (file->device->disk->partition)) + { + grub_free (bootpart); + bootpart = grub_strndup (pmap + pstart, pend - pstart); + } + pmapptr += grub_strlen (pmap + pmapptr); return 0; } @@ -198,9 +215,9 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) int fill_disk (const char *name) { grub_device_t dev; - int file_disk; char *plan9name = NULL; unsigned i; + int file_disk = 0; dev = grub_device_open (name); if (!dev) @@ -304,7 +321,13 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } grub_strcpy (pmap + pmapptr, plan9name); pmapptr += grub_strlen (plan9name); - grub_free (plan9name); + if (!file_disk) + grub_free (plan9name); + else + { + grub_free (bootdisk); + bootdisk = plan9name; + } grub_strcpy (pmap + pmapptr, "part="); pmapptr += sizeof ("part=") - 1; @@ -344,6 +367,25 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) goto fail; pmap[pmapptr] = 0; + { + char *file_name = grub_strchr (argv[0], ')'); + if (file_name) + file_name++; + else + file_name = argv[0]; + if (*file_name) + file_name++; + + if (bootpart) + bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name); + else + bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name); + grub_free (bootdisk); + grub_free (bootpart); + } + if (!bootpath) + goto fail; + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) goto fail; @@ -369,6 +411,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) for (i = 1; i < argc; i++) configsize += grub_strlen (argv[i]) + 1; } + configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; configsize += pmapptr; /* Terminating \0. */ configsize++; @@ -384,10 +427,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } grub_memset (config, 0, GRUB_PLAN9_CONFIG_PATH_SIZE); + grub_strncpy (config, bootpath, GRUB_PLAN9_CONFIG_PATH_SIZE - 1); + configptr = config + GRUB_PLAN9_CONFIG_PATH_SIZE; grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + configptr = grub_stpcpy (configptr, "bootfile="); + configptr = grub_stpcpy (configptr, bootpath); + *configptr++ = '\n'; { int i; for (i = 1; i < argc; i++) From 406a552051bdda5fa07de20a10ccfa7910ca946b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 10:43:04 +0100 Subject: [PATCH 022/315] Add plan9 to OS support table --- docs/grub.texi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/grub.texi b/docs/grub.texi index 54a2d8791..6878a645a 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3305,6 +3305,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab BIOS @tab Coreboot @item BIOS chainloading @tab yes @tab no (1) @item NTLDR @tab yes @tab no (1) +@item Plan9 @tab yes @tab no (1) @item FreeBSD bootloader @tab yes @tab crashes (1) @item 32-bit kFreeBSD @tab yes @tab crashes (2,6) @item 64-bit kFreeBSD @tab yes @tab crashes (2,6) @@ -3329,6 +3330,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab Multiboot @tab Qemu @item BIOS chainloading @tab no (1) @tab no (1) @item NTLDR @tab no (1) @tab no (1) +@item Plan9 @tab no (1) @tab no (1) @item FreeBSD bootloader @tab crashes (1) @tab crashes (1) @item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6) @item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6) @@ -3353,6 +3355,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab 32-bit EFI @tab 64-bit EFI @item BIOS chainloading @tab no (1) @tab no (1) @item NTLDR @tab no (1) @tab no (1) +@item Plan9 @tab no (1) @tab no (1) @item FreeBSD bootloader @tab crashes (1) @tab crashes (1) @item 32-bit kFreeBSD @tab headless @tab headless @item 64-bit kFreeBSD @tab headless @tab headless @@ -3377,6 +3380,7 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel @item @tab IEEE1275 @item BIOS chainloading @tab no (1) @item NTLDR @tab no (1) +@item Plan9 @tab no (1) @item FreeBSD bootloader @tab crashes (1) @item 32-bit kFreeBSD @tab crashes (6) @item 64-bit kFreeBSD @tab crashes (6) From 92bb078645e55f116ebb253be5292cd10b6ffbb9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 19:51:08 +0100 Subject: [PATCH 023/315] grub-fuse --- Makefile.util.def | 15 ++ config.h.in | 4 + configure.ac | 37 ++++ docs/man/grub-fuse.h2m | 2 + util/grub-fuse.c | 455 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 513 insertions(+) create mode 100644 docs/man/grub-fuse.h2m create mode 100644 util/grub-fuse.c diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..369d312f6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -212,6 +212,21 @@ program = { ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; +program = { + name = grub-fuse; + mansection = 1; + common_nodist = grub_fstest_init.c; + common = util/grub-fuse.c; + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; + + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; + condition = COND_GRUB_FUSE; +}; + program = { name = grub-mkfont; mansection = 1; diff --git a/config.h.in b/config.h.in index 6d7d95dec..3974ad7d5 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,7 @@ +#undef _LARGEFILE_SOURCE +#undef _FILE_OFFSET_BITS +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #include #define NESTED_FUNC_ATTR diff --git a/configure.ac b/configure.ac index 8bb585a78..e9e31e7fb 100644 --- a/configure.ac +++ b/configure.ac @@ -856,6 +856,37 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([grub-mkfont], + [AS_HELP_STRING([--enable-grub-mkfont], + [build and install the `grub-mkfont' utility (default=guessed)])]) +if test x"$enable_grub_mkfont" = xno ; then + grub_mkfont_excuse="explicitly disabled" +fi + +if test x"$grub_fuse_excuse" = x ; then + AC_CHECK_LIB([fuse], [fuse_main_real], [], + [grub_fuse_excuse="need FUSE library"]) +fi + +if test x"$grub_fuse_excuse" = x ; then + # Check for fuse headers. + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + AC_CHECK_HEADERS([fuse/fuse.h], [], + [grub_fuse_excuse=["need FUSE headers"]]) + CPPFLAGS="$SAVED_CPPFLAGS" +fi + +if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then + AC_MSG_ERROR([grub-fuse was explicitly requested but can't be compiled]) +fi +if test x"$grub_fuse_excuse" = x ; then +enable_grub_fuse=yes +else +enable_grub_fuse=no +fi +AC_SUBST([enable_grub_fuse]) + AC_ARG_ENABLE([device-mapper], [AS_HELP_STRING([--enable-device-mapper], [enable Linux device-mapper support (default=guessed)])]) @@ -952,6 +983,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) +AM_CONDITIONAL([COND_GRUB_FUSE], [test x$enable_grub_fuse = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) @@ -1027,5 +1059,10 @@ echo grub-mkfont: Yes else echo grub-mkfont: No "($grub_mkfont_excuse)" fi +if [ x"$grub_fuse_excuse" = x ]; then +echo grub-fuse: Yes +else +echo grub-fuse: No "($grub_fuse_excuse)" +fi echo "*******************************************************" ] diff --git a/docs/man/grub-fuse.h2m b/docs/man/grub-fuse.h2m new file mode 100644 index 000000000..0e234ddc1 --- /dev/null +++ b/docs/man/grub-fuse.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-fuse \- export GRUB filesystem with FUSE. diff --git a/util/grub-fuse.c b/util/grub-fuse.c new file mode 100644 index 000000000..7f0ad0d0f --- /dev/null +++ b/util/grub-fuse.c @@ -0,0 +1,455 @@ +/* grub-fstest.c - debug tool for filesystem driver */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ +#define FUSE_USE_VERSION 26 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "progname.h" +#include "argp.h" + +static char *root = NULL; +static char **images = NULL; +static char *debug_str = NULL; +static char **fuse_args = NULL; +static int fuse_argc = 0; +static int num_disks = 0; + +static grub_err_t +execute_command (char *name, int n, char **args) +{ + grub_command_t cmd; + + cmd = grub_command_find (name); + if (! cmd) + grub_util_error (_("can\'t find command %s"), name); + + return (cmd->func) (cmd, n, args); +} + +static int +fuse_getattr (const char *path, struct stat *st) +{ + char *filename, *pathname, *path2; + const char *pathname_t; + grub_fs_t fs; + grub_device_t dev; + struct grub_dirhook_info file_info; + int file_exists = 0; + + /* A hook for iterating directories. */ + auto int find_file (const char *cur_filename, + const struct grub_dirhook_info *info); + int find_file (const char *cur_filename, + const struct grub_dirhook_info *info) + { + if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename) + : grub_strcmp (cur_filename, filename)) == 0) + { + file_info = *info; + file_exists = 1; + return 1; + } + return 0; + } + + if (path[0] == '/' && path[1] == 0) + { + st->st_dev = 0; + st->st_ino = 0; + st->st_mode = 0555 | S_IFDIR; + st->st_uid = 0; + st->st_gid = 0; + st->st_rdev = 0; + st->st_size = 0; + st->st_blksize = 512; + st->st_blocks = (st->st_blksize + 511) >> 9; + st->st_atime = st->st_mtime = st->st_ctime = 0; + return 0; + } + + file_exists = 0; + dev = grub_device_open (0); + if (! dev) + return -1; + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return -1; + } + + pathname_t = grub_strchr (path, ')'); + if (! pathname_t) + pathname_t = path; + else + pathname_t++; + pathname = xstrdup (pathname_t); + + /* Remove trailing '/'. */ + while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + + /* Split into path and filename. */ + filename = grub_strrchr (pathname, '/'); + if (! filename) + { + path2 = grub_strdup ("/"); + filename = pathname; + } + else + { + filename++; + path2 = grub_strdup (pathname); + path2[filename - pathname] = 0; + } + + /* It's the whole device. */ + (fs->dir) (dev, path2, find_file); + + grub_device_close (dev); + grub_free (path2); + if (!file_exists) + return -1; + st->st_dev = 0; + st->st_ino = 0; + st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); + st->st_uid = 0; + st->st_gid = 0; + st->st_rdev = 0; + if (!file_info.dir) + { + grub_file_t file; + file = grub_file_open (path); + if (! file) + { + grub_print_error (); + return -1; + } + st->st_size = file->size; + grub_file_close (file); + } + else + st->st_size = 0; + st->st_blksize = 512; + st->st_blocks = (st->st_size + 511) >> 9; + st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset + ? file_info.mtime : 0; + return 0; +} + +static int +fuse_opendir (const char *path, struct fuse_file_info *fi) +{ + return 0; +} + +/* FIXME */ +static grub_file_t files[65536]; +static int first_fd = 1; + +static int +fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) +{ + grub_file_t file; + file = grub_file_open (path); + if (! file) + { + grub_print_error (); + return -1; + } + files[first_fd++] = file; + fi->fh = first_fd; + files[first_fd++] = file; + return 0; +} + +static int +fuse_read (const char *path, char *buf, size_t sz, off_t off, + struct fuse_file_info *fi) +{ + grub_file_t file = files[fi->fh]; + + if (off > file->size) + return -1; + + file->offset = off; + + return grub_file_read (file, buf, sz); +} + +static int +fuse_release (const char *path, struct fuse_file_info *fi) +{ + grub_file_close (files[fi->fh]); + files[fi->fh] = NULL; + return 0; +} + +static int +fuse_readdir (const char *path, void *buf, + fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) +{ + char *pathname; + grub_fs_t fs; + grub_device_t dev; + + auto int call_fill (const char *filename, + const struct grub_dirhook_info *info); + int call_fill (const char *filename, const struct grub_dirhook_info *info) + { + fill (buf, filename, NULL, 0); + return 0; + } + + dev = grub_device_open (0); + if (! dev) + { + return 1; + } + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return 1; + } + + pathname = xstrdup (path); + + /* Remove trailing '/'. */ + while (pathname [0] && pathname[1] + && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + + (fs->dir) (dev, pathname, call_fill); + grub_device_close (dev); + free (pathname); + return 0; +} + +struct fuse_operations grub_opers = { + .getattr = fuse_getattr, + .open = fuse_open, + .release = fuse_release, + .opendir = fuse_opendir, + .readdir = fuse_readdir, + .read = fuse_read +}; + +static void +fuse_init (void) +{ + int i; + + for (i = 0; i < num_disks; i++) + { + char *argv[2]; + char *host_file; + char *loop_name; + loop_name = grub_xasprintf ("loop%d", i); + if (!loop_name) + grub_util_error (grub_errmsg); + + host_file = grub_xasprintf ("(host)%s", images[i]); + if (!host_file) + grub_util_error (grub_errmsg); + + argv[0] = loop_name; + argv[1] = host_file; + + if (execute_command ("loopback", 2, argv)) + grub_util_error (_("loopback command fails")); + + grub_free (loop_name); + grub_free (host_file); + } + + grub_lvm_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); + grub_lvm_init (); + + fuse_main (fuse_argc, fuse_args, &grub_opers, NULL); + + for (i = 0; i < num_disks; i++) + { + char *argv[2]; + char *loop_name; + + loop_name = grub_xasprintf ("loop%d", i); + if (!loop_name) + grub_util_error (grub_errmsg); + + argv[0] = "-d"; + argv[1] = loop_name; + + execute_command ("loopback", 2, argv); + + grub_free (loop_name); + } +} + +static struct argp_option options[] = { + {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, + {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, + {0, 0, 0, 0, 0, 0} +}; + +/* Print the version information. */ +static void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); +} +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + char *p; + + switch (key) + { + case 'r': + root = arg; + return 0; + + case 'd': + debug_str = arg; + return 0; + + case 'v': + verbosity++; + return 0; + + case ARGP_KEY_ARG: + if (arg[0] != '-') + break; + + default: + if (!arg) + return 0; + + fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = xstrdup (arg); + fuse_argc++; + return 0; + } + + if (arg[0] != '/') + { + fprintf (stderr, "%s", _("Must use absolute path.\n")); + argp_usage (state); + } + images = xrealloc (images, (num_disks + 1) * sizeof (images[0])); + images[num_disks] = xstrdup (arg); + num_disks++; + + return 0; +} + +struct argp argp = { + options, argp_parser, N_("IMAGE1 [IMAGE2 ...] MOUNTPOINT"), + N_("Debug tool for filesystem driver."), + NULL, NULL, NULL +}; + +int +main (int argc, char *argv[]) +{ + char *default_root, *alloc_root; + + set_program_name (argv[0]); + + grub_util_init_nls (); + + fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = xstrdup (argv[0]); + fuse_argc++; + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (num_disks < 2) + grub_util_error ("need an image and mountpoint"); + fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = images[num_disks - 1]; + fuse_argc++; + num_disks--; + fuse_args[fuse_argc] = NULL; + + /* Initialize all modules. */ + grub_init_all (); + + if (debug_str) + grub_env_set ("debug", debug_str); + + default_root = (num_disks == 1) ? "loop0" : "md0"; + alloc_root = 0; + if (root) + { + if ((*root >= '0') && (*root <= '9')) + { + alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2); + + sprintf (alloc_root, "%s,%s", default_root, root); + root = alloc_root; + } + } + else + root = default_root; + + grub_env_set ("root", root); + + if (alloc_root) + free (alloc_root); + + /* Do it. */ + fuse_init (); + + /* Free resources. */ + grub_fini_all (); + + return 0; +} From 89644ef113f00c03b18d075243debf5417e00549 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 11 Jan 2011 21:20:54 +0100 Subject: [PATCH 024/315] Rename grub-fuse to grub-mount (with Vladimir's blessing) --- Makefile.util.def | 4 ++-- configure.ac | 6 +++--- docs/man/grub-fuse.h2m | 2 -- docs/man/grub-mount.h2m | 2 ++ util/{grub-fuse.c => grub-mount.c} | 0 5 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 docs/man/grub-fuse.h2m create mode 100644 docs/man/grub-mount.h2m rename util/{grub-fuse.c => grub-mount.c} (100%) diff --git a/Makefile.util.def b/Makefile.util.def index 369d312f6..3009ff76a 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -213,10 +213,10 @@ program = { }; program = { - name = grub-fuse; + name = grub-mount; mansection = 1; common_nodist = grub_fstest_init.c; - common = util/grub-fuse.c; + common = util/grub-mount.c; common = grub-core/kern/emu/hostfs.c; common = grub-core/disk/host.c; diff --git a/configure.ac b/configure.ac index e9e31e7fb..b71aea910 100644 --- a/configure.ac +++ b/configure.ac @@ -878,7 +878,7 @@ if test x"$grub_fuse_excuse" = x ; then fi if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then - AC_MSG_ERROR([grub-fuse was explicitly requested but can't be compiled]) + AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled]) fi if test x"$grub_fuse_excuse" = x ; then enable_grub_fuse=yes @@ -1060,9 +1060,9 @@ else echo grub-mkfont: No "($grub_mkfont_excuse)" fi if [ x"$grub_fuse_excuse" = x ]; then -echo grub-fuse: Yes +echo grub-mount: Yes else -echo grub-fuse: No "($grub_fuse_excuse)" +echo grub-mount: No "($grub_fuse_excuse)" fi echo "*******************************************************" ] diff --git a/docs/man/grub-fuse.h2m b/docs/man/grub-fuse.h2m deleted file mode 100644 index 0e234ddc1..000000000 --- a/docs/man/grub-fuse.h2m +++ /dev/null @@ -1,2 +0,0 @@ -[NAME] -grub-fuse \- export GRUB filesystem with FUSE. diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m new file mode 100644 index 000000000..73e7246a3 --- /dev/null +++ b/docs/man/grub-mount.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mount \- export GRUB filesystem with FUSE. diff --git a/util/grub-fuse.c b/util/grub-mount.c similarity index 100% rename from util/grub-fuse.c rename to util/grub-mount.c From b0bfc5937d6232c01dbb44f7ad3135eb5aa07ff8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:31:32 +0100 Subject: [PATCH 025/315] fix header comment --- util/grub-mount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index 7f0ad0d0f..c1c7ecad8 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -1,4 +1,4 @@ -/* grub-fstest.c - debug tool for filesystem driver */ +/* grub-mount.c - FUSE driver for filesystems that GRUB understands */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. From 9aa6fcc17e7b7d6e1712a0cc400c39b44a6e6a72 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:38:41 +0100 Subject: [PATCH 026/315] fix duplicate --enable-grub-mkfont option; this should be --enable-grub-fuse instead --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index b71aea910..12ac0e917 100644 --- a/configure.ac +++ b/configure.ac @@ -856,11 +856,11 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) -AC_ARG_ENABLE([grub-mkfont], - [AS_HELP_STRING([--enable-grub-mkfont], - [build and install the `grub-mkfont' utility (default=guessed)])]) -if test x"$enable_grub_mkfont" = xno ; then - grub_mkfont_excuse="explicitly disabled" +AC_ARG_ENABLE([grub-fuse], + [AS_HELP_STRING([--enable-grub-fuse], + [build and install the `grub-fuse' utility (default=guessed)])]) +if test x"$enable_grub_fuse" = xno ; then + grub_fuse_excuse="explicitly disabled" fi if test x"$grub_fuse_excuse" = x ; then From 897e62079e0bab32f089a44b791116493d34ef45 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:43:12 +0100 Subject: [PATCH 027/315] rename grub-fuse to grub-mount throughout configuration --- Makefile.util.def | 2 +- configure.ac | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 3009ff76a..cd37d0d65 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -224,7 +224,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; - condition = COND_GRUB_FUSE; + condition = COND_GRUB_MOUNT; }; program = { diff --git a/configure.ac b/configure.ac index 12ac0e917..d1eaa0c84 100644 --- a/configure.ac +++ b/configure.ac @@ -856,36 +856,36 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) -AC_ARG_ENABLE([grub-fuse], - [AS_HELP_STRING([--enable-grub-fuse], - [build and install the `grub-fuse' utility (default=guessed)])]) -if test x"$enable_grub_fuse" = xno ; then - grub_fuse_excuse="explicitly disabled" +AC_ARG_ENABLE([grub-mount], + [AS_HELP_STRING([--enable-grub-mount], + [build and install the `grub-mount' utility (default=guessed)])]) +if test x"$enable_grub_mount" = xno ; then + grub_mount_excuse="explicitly disabled" fi -if test x"$grub_fuse_excuse" = x ; then +if test x"$grub_mount_excuse" = x ; then AC_CHECK_LIB([fuse], [fuse_main_real], [], - [grub_fuse_excuse="need FUSE library"]) + [grub_mount_excuse="need FUSE library"]) fi -if test x"$grub_fuse_excuse" = x ; then +if test x"$grub_mount_excuse" = x ; then # Check for fuse headers. SAVED_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" AC_CHECK_HEADERS([fuse/fuse.h], [], - [grub_fuse_excuse=["need FUSE headers"]]) + [grub_mount_excuse=["need FUSE headers"]]) CPPFLAGS="$SAVED_CPPFLAGS" fi -if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then +if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled]) fi -if test x"$grub_fuse_excuse" = x ; then -enable_grub_fuse=yes +if test x"$grub_mount_excuse" = x ; then +enable_grub_mount=yes else -enable_grub_fuse=no +enable_grub_mount=no fi -AC_SUBST([enable_grub_fuse]) +AC_SUBST([enable_grub_mount]) AC_ARG_ENABLE([device-mapper], [AS_HELP_STRING([--enable-device-mapper], @@ -983,7 +983,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) -AM_CONDITIONAL([COND_GRUB_FUSE], [test x$enable_grub_fuse = xyes]) +AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) @@ -1059,10 +1059,10 @@ echo grub-mkfont: Yes else echo grub-mkfont: No "($grub_mkfont_excuse)" fi -if [ x"$grub_fuse_excuse" = x ]; then +if [ x"$grub_mount_excuse" = x ]; then echo grub-mount: Yes else -echo grub-mount: No "($grub_fuse_excuse)" +echo grub-mount: No "($grub_mount_excuse)" fi echo "*******************************************************" ] From f387685926dc0dedfa8eace8a76955c845e25a84 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 11:45:10 +0100 Subject: [PATCH 028/315] remove trailing full stop, for consistency with other pages --- docs/man/grub-mount.h2m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m index 73e7246a3..8d168982d 100644 --- a/docs/man/grub-mount.h2m +++ b/docs/man/grub-mount.h2m @@ -1,2 +1,2 @@ [NAME] -grub-mount \- export GRUB filesystem with FUSE. +grub-mount \- export GRUB filesystem with FUSE From 5b3633002b9fb95c830a4c339c64a25fa43013ea Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 10 Apr 2011 21:41:55 +0100 Subject: [PATCH 029/315] Make grub-mount exit non-zero if opening the device or filesystem fails. Translate GRUB error codes into OS error codes for FUSE. --- util/grub-mount.c | 132 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 41 deletions(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index c1c7ecad8..efada771a 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -44,6 +44,8 @@ #include "argp.h" static char *root = NULL; +grub_device_t dev = NULL; +grub_fs_t fs = NULL; static char **images = NULL; static char *debug_str = NULL; static char **fuse_args = NULL; @@ -62,13 +64,61 @@ execute_command (char *name, int n, char **args) return (cmd->func) (cmd, n, args); } +/* Translate GRUB error numbers into OS error numbers. Print any unexpected + errors. */ +static int +translate_error (void) +{ + int ret; + + switch (grub_errno) + { + case GRUB_ERR_NONE: + ret = 0; + break; + + case GRUB_ERR_OUT_OF_MEMORY: + grub_print_error (); + ret = -ENOMEM; + break; + + case GRUB_ERR_BAD_FILE_TYPE: + /* This could also be EISDIR. Take a guess. */ + ret = -ENOTDIR; + break; + + case GRUB_ERR_FILE_NOT_FOUND: + ret = -ENOENT; + break; + + case GRUB_ERR_FILE_READ_ERROR: + case GRUB_ERR_READ_ERROR: + case GRUB_ERR_IO: + grub_print_error (); + ret = -EIO; + break; + + case GRUB_ERR_SYMLINK_LOOP: + ret = -ELOOP; + break; + + default: + grub_print_error (); + ret = -EINVAL; + break; + } + + /* Any previous errors were handled. */ + grub_errno = GRUB_ERR_NONE; + + return ret; +} + static int fuse_getattr (const char *path, struct stat *st) { char *filename, *pathname, *path2; const char *pathname_t; - grub_fs_t fs; - grub_device_t dev; struct grub_dirhook_info file_info; int file_exists = 0; @@ -104,16 +154,6 @@ fuse_getattr (const char *path, struct stat *st) } file_exists = 0; - dev = grub_device_open (0); - if (! dev) - return -1; - - fs = grub_fs_probe (dev); - if (! fs) - { - grub_device_close (dev); - return -1; - } pathname_t = grub_strchr (path, ')'); if (! pathname_t) @@ -143,10 +183,12 @@ fuse_getattr (const char *path, struct stat *st) /* It's the whole device. */ (fs->dir) (dev, path2, find_file); - grub_device_close (dev); grub_free (path2); if (!file_exists) - return -1; + { + grub_errno = GRUB_ERR_NONE; + return -ENOENT; + } st->st_dev = 0; st->st_ino = 0; st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); @@ -158,10 +200,7 @@ fuse_getattr (const char *path, struct stat *st) grub_file_t file; file = grub_file_open (path); if (! file) - { - grub_print_error (); - return -1; - } + return translate_error (); st->st_size = file->size; grub_file_close (file); } @@ -171,6 +210,7 @@ fuse_getattr (const char *path, struct stat *st) st->st_blocks = (st->st_size + 511) >> 9; st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset ? file_info.mtime : 0; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -190,13 +230,11 @@ fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) grub_file_t file; file = grub_file_open (path); if (! file) - { - grub_print_error (); - return -1; - } + return translate_error (); files[first_fd++] = file; fi->fh = first_fd; files[first_fd++] = file; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -205,13 +243,21 @@ fuse_read (const char *path, char *buf, size_t sz, off_t off, struct fuse_file_info *fi) { grub_file_t file = files[fi->fh]; + grub_ssize_t size; if (off > file->size) - return -1; + return -EINVAL; file->offset = off; - return grub_file_read (file, buf, sz); + size = grub_file_read (file, buf, sz); + if (size < 0) + return translate_error (); + else + { + grub_errno = GRUB_ERR_NONE; + return size; + } } static int @@ -219,6 +265,7 @@ fuse_release (const char *path, struct fuse_file_info *fi) { grub_file_close (files[fi->fh]); files[fi->fh] = NULL; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -227,8 +274,6 @@ fuse_readdir (const char *path, void *buf, fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) { char *pathname; - grub_fs_t fs; - grub_device_t dev; auto int call_fill (const char *filename, const struct grub_dirhook_info *info); @@ -238,19 +283,6 @@ fuse_readdir (const char *path, void *buf, return 0; } - dev = grub_device_open (0); - if (! dev) - { - return 1; - } - - fs = grub_fs_probe (dev); - if (! fs) - { - grub_device_close (dev); - return 1; - } - pathname = xstrdup (path); /* Remove trailing '/'. */ @@ -259,8 +291,8 @@ fuse_readdir (const char *path, void *buf, pathname[grub_strlen (pathname) - 1] = 0; (fs->dir) (dev, pathname, call_fill); - grub_device_close (dev); free (pathname); + grub_errno = GRUB_ERR_NONE; return 0; } @@ -273,7 +305,7 @@ struct fuse_operations grub_opers = { .read = fuse_read }; -static void +static grub_err_t fuse_init (void) { int i; @@ -310,6 +342,17 @@ fuse_init (void) grub_mdraid1x_init (); grub_lvm_init (); + dev = grub_device_open (0); + if (! dev) + return grub_errno; + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return grub_errno; + } + fuse_main (fuse_argc, fuse_args, &grub_opers, NULL); for (i = 0; i < num_disks; i++) @@ -328,6 +371,8 @@ fuse_init (void) grub_free (loop_name); } + + return GRUB_ERR_NONE; } static struct argp_option options[] = { @@ -447,6 +492,11 @@ main (int argc, char *argv[]) /* Do it. */ fuse_init (); + if (grub_errno) + { + grub_print_error (); + return 1; + } /* Free resources. */ grub_fini_all (); From 4ac93e6c4f8137a32a9591caf9cf7e2af234c12b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 10 Apr 2011 22:12:23 +0100 Subject: [PATCH 030/315] add grub-mount to .bzrignore --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 0cbb3f17f..d4d5987ec 100644 --- a/.bzrignore +++ b/.bzrignore @@ -44,6 +44,7 @@ grub-kbdcomp grub-macho2img grub-menulst2cfg grub-mk* +grub-mount grub-pbkdf2 grub-pe2elf grub-probe From 48fe18dcf2d2003846046a808d984a4db0a336ba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 18:13:00 +0200 Subject: [PATCH 031/315] exfat reader --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/exfat.c | 2 + grub-core/fs/fat.c | 369 ++++++++++++++++++++++++++++++++++-- 4 files changed, 359 insertions(+), 18 deletions(-) create mode 100644 grub-core/fs/exfat.c diff --git a/Makefile.util.def b/Makefile.util.def index 303baea3f..a1d00a683 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -53,6 +53,7 @@ library = { common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; common = grub-core/fs/fat.c; + common = grub-core/fs/exfat.c; common = grub-core/fs/fshelp.c; common = grub-core/fs/hfs.c; common = grub-core/fs/hfsplus.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7c26b37e9..3ec41ac7f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -923,6 +923,11 @@ module = { common = fs/fat.c; }; +module = { + name = exfat; + common = fs/exfat.c; +}; + module = { name = fshelp; common = fs/fshelp.c; diff --git a/grub-core/fs/exfat.c b/grub-core/fs/exfat.c new file mode 100644 index 000000000..fe149ddd3 --- /dev/null +++ b/grub-core/fs/exfat.c @@ -0,0 +1,2 @@ +#define MODE_EXFAT 1 +#include "fat.c" diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 89050943c..5f7a58571 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -32,23 +32,54 @@ #define GRUB_FAT_ATTR_READ_ONLY 0x01 #define GRUB_FAT_ATTR_HIDDEN 0x02 #define GRUB_FAT_ATTR_SYSTEM 0x04 +#ifndef MODE_EXFAT #define GRUB_FAT_ATTR_VOLUME_ID 0x08 +#endif #define GRUB_FAT_ATTR_DIRECTORY 0x10 #define GRUB_FAT_ATTR_ARCHIVE 0x20 #define GRUB_FAT_MAXFILE 256 +#ifndef MODE_EXFAT #define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \ | GRUB_FAT_ATTR_HIDDEN \ | GRUB_FAT_ATTR_SYSTEM \ | GRUB_FAT_ATTR_VOLUME_ID) -#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \ - | GRUB_FAT_ATTR_HIDDEN \ - | GRUB_FAT_ATTR_SYSTEM \ - | GRUB_FAT_ATTR_DIRECTORY \ - | GRUB_FAT_ATTR_ARCHIVE \ - | GRUB_FAT_ATTR_VOLUME_ID) +#endif +static const grub_uint8_t GRUB_FAT_ATTR_VALID = (GRUB_FAT_ATTR_READ_ONLY + | GRUB_FAT_ATTR_HIDDEN + | GRUB_FAT_ATTR_SYSTEM + | GRUB_FAT_ATTR_DIRECTORY + | GRUB_FAT_ATTR_ARCHIVE +#ifndef MODE_EXFAT + | GRUB_FAT_ATTR_VOLUME_ID +#endif + ); +#ifdef MODE_EXFAT +struct grub_fat_bpb +{ + grub_uint8_t jmp_boot[3]; + grub_uint8_t oem_name[8]; + grub_uint8_t mbz[53]; + grub_uint64_t num_hidden_sectors; + grub_uint64_t num_total_sectors; + grub_uint32_t num_reserved_sectors; + grub_uint32_t sectors_per_fat; + grub_uint32_t cluster_offset; + grub_uint32_t cluster_count; + grub_uint32_t root_cluster; + grub_uint32_t num_serial; + grub_uint16_t fs_revision; + grub_uint16_t volume_flags; + grub_uint8_t bytes_per_sector_shift; + grub_uint8_t sectors_per_cluster_shift; + grub_uint8_t num_fats; + grub_uint8_t num_ph_drive; + grub_uint8_t reserved[8]; +} __attribute__ ((packed)); + +#else struct grub_fat_bpb { grub_uint8_t jmp_boot[3]; @@ -94,7 +125,64 @@ struct grub_fat_bpb } __attribute__ ((packed)) fat32; } __attribute__ ((packed)) version_specific; } __attribute__ ((packed)); +#endif +#ifdef MODE_EXFAT +struct grub_fat_dir_entry +{ + grub_uint8_t entry_type; + union + { + grub_uint8_t placeholder[31]; + struct { + grub_uint8_t secondary_count; + grub_uint16_t checksum; + grub_uint16_t attr; + grub_uint16_t reserved1; + grub_uint32_t c_time; + grub_uint32_t m_time; + grub_uint32_t a_time; + grub_uint8_t c_time_tenth; + grub_uint8_t m_time_tenth; + grub_uint8_t a_time_tenth; + grub_uint8_t reserved2[9]; + } __attribute__ ((packed)) file; + struct { + grub_uint8_t flags; + grub_uint8_t reserved1; + grub_uint8_t name_length; + grub_uint16_t name_hash; + grub_uint16_t reserved2; + grub_uint64_t valid_size; + grub_uint32_t reserved3; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + } __attribute__ ((packed)) stream_extension; + struct { + grub_uint8_t flags; + grub_uint16_t str[15]; + } __attribute__ ((packed)) file_name; + struct { + grub_uint8_t character_count; + grub_uint16_t str[11]; + grub_uint8_t reserved[8]; + } __attribute__ ((packed)) volume_label; + } __attribute__ ((packed)) type_specific; +} __attribute__ ((packed)); + +struct grub_fat_dir_node +{ + grub_uint32_t attr; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + grub_uint64_t valid_size; + int have_stream; + int is_label; +}; + +typedef struct grub_fat_dir_node grub_fat_dir_node_t; + +#else struct grub_fat_dir_entry { grub_uint8_t name[11]; @@ -123,6 +211,10 @@ struct grub_fat_long_name_entry grub_uint16_t name3[2]; } __attribute__ ((packed)); +typedef struct grub_fat_dir_entry grub_fat_dir_node_t; + +#endif + struct grub_fat_data { int logical_sector_bits; @@ -133,8 +225,10 @@ struct grub_fat_data int fat_size; grub_uint32_t root_cluster; +#ifndef MODE_EXFAT grub_uint32_t root_sector; grub_uint32_t num_root_sectors; +#endif int cluster_bits; grub_uint32_t cluster_eof_mark; @@ -152,6 +246,7 @@ struct grub_fat_data static grub_dl_t my_mod; +#ifndef MODE_EXFAT static int fat_log2 (unsigned x) { @@ -168,6 +263,7 @@ fat_log2 (unsigned x) return i; } +#endif static struct grub_fat_data * grub_fat_mount (grub_disk_t disk) @@ -187,20 +283,37 @@ grub_fat_mount (grub_disk_t disk) if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) goto fail; +#ifdef MODE_EXFAT + if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ", + sizeof (bpb.oem_name)) != 0) + goto fail; +#else if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5) && grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5) && grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5)) goto fail; +#endif + + grub_dprintf ("exfat", "alive\n"); /* Get the sizes of logical sectors and clusters. */ +#ifdef MODE_EXFAT + data->logical_sector_bits = bpb.bytes_per_sector_shift; +#else data->logical_sector_bits = fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); - if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS) +#endif + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS + || data->logical_sector_bits >= 16) goto fail; data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS; +#ifdef MODE_EXFAT + data->cluster_bits = bpb.sectors_per_cluster_shift; +#else data->cluster_bits = fat_log2 (bpb.sectors_per_cluster); - if (data->cluster_bits < 0) +#endif + if (data->cluster_bits < 0 || data->cluster_bits > 25) goto fail; data->cluster_bits += data->logical_sector_bits; @@ -210,18 +323,28 @@ grub_fat_mount (grub_disk_t disk) if (data->fat_sector == 0) goto fail; +#ifdef MODE_EXFAT + data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat) + << data->logical_sector_bits); +#else data->sectors_per_fat = ((bpb.sectors_per_fat_16 ? grub_le_to_cpu16 (bpb.sectors_per_fat_16) : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)) << data->logical_sector_bits); +#endif if (data->sectors_per_fat == 0) goto fail; /* Get the number of sectors in this volume. */ +#ifdef MODE_EXFAT + data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors)) + << data->logical_sector_bits); +#else data->num_sectors = ((bpb.num_total_sectors_16 ? grub_le_to_cpu16 (bpb.num_total_sectors_16) : grub_le_to_cpu32 (bpb.num_total_sectors_32)) << data->logical_sector_bits); +#endif if (data->num_sectors == 0) goto fail; @@ -229,6 +352,9 @@ grub_fat_mount (grub_disk_t disk) if (bpb.num_fats == 0) goto fail; + grub_dprintf ("exfat", "alive\n"); + +#ifndef MODE_EXFAT data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat; data->num_root_sectors = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries) @@ -236,15 +362,36 @@ grub_fat_mount (grub_disk_t disk) + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1) >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS)) << (data->logical_sector_bits)); +#endif +#ifdef MODE_EXFAT + data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset) + << data->logical_sector_bits); + data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count) + << data->logical_sector_bits); +#else data->cluster_sector = data->root_sector + data->num_root_sectors; data->num_clusters = (((data->num_sectors - data->cluster_sector) >> (data->cluster_bits + data->logical_sector_bits)) + 2); +#endif if (data->num_clusters <= 2) goto fail; +#ifdef MODE_EXFAT + { + /* exFAT. */ + grub_uint16_t flags = grub_le_to_cpu16 (bpb.volume_flags); + + data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0xffffffff; + + if ((flags & 0x1) && bpb.num_fats > 1) + data->fat_sector += data->sectors_per_fat; + } +#else if (! bpb.sectors_per_fat_16) { /* FAT32. */ @@ -286,6 +433,7 @@ grub_fat_mount (grub_disk_t disk) data->cluster_eof_mark = 0xfff8; } } +#endif /* More sanity checks. */ if (data->num_sectors <= data->fat_sector) @@ -317,17 +465,23 @@ grub_fat_mount (grub_disk_t disk) } /* Serial number. */ +#ifdef MODE_EXFAT + data->uuid = grub_le_to_cpu32 (bpb.num_serial); +#else if (bpb.sectors_per_fat_16) data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); else data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial); +#endif +#ifndef MODE_EXFAT /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media descriptor, even if it is a so-called superfloppy (e.g. an USB key). The check may be too strict for this kind of stupid BIOSes, as they overwrite the media descriptor. */ if ((first_fat | 0x8) != (magic | bpb.media | 0x8)) goto fail; +#endif /* Start from the root directory. */ data->file_cluster = data->root_cluster; @@ -354,6 +508,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, grub_ssize_t ret = 0; unsigned long sector; +#ifndef MODE_EXFAT /* This is a special case. FAT12 and FAT16 doesn't have the root directory in clusters. */ if (data->file_cluster == ~0U) @@ -367,6 +522,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, return size; } +#endif /* Calculate the logical cluster number and offset. */ logical_cluster_bits = (data->cluster_bits @@ -465,13 +621,115 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, return ret; } +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, + int (*hook) (const char *filename, + grub_fat_dir_node_t *node)) +{ + struct grub_fat_dir_entry dir; + grub_ssize_t offset = -sizeof(dir); + grub_uint16_t *unibuf; + char *filename; + + unibuf = grub_malloc (15 * 256 * 2); + filename = grub_malloc (15 * 256 * 4 + 1); + + while (1) + { + offset += sizeof (dir); + + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + if (dir.entry_type == 0x85) + { + unsigned i, nsec, slots = 0; + grub_fat_dir_node_t node; + + nsec = dir.type_specific.file.secondary_count; + + node.attr = grub_cpu_to_le32 (dir.type_specific.file.attr); + node.have_stream = 0; + for (i = 0; i < nsec; i++) + { + struct grub_fat_dir_entry sec; + offset += sizeof (sec); + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (sec), (char *) &sec) + != sizeof (sec)) + break; + if (!(sec.entry_type & 0x80)) + continue; + if (!(sec.entry_type & 0x40)) + break; + switch (sec.entry_type) + { + case 0xc0: + node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); + node.valid_size + = grub_cpu_to_le32 (sec.type_specific.stream_extension.valid_size); + node.file_size + = grub_cpu_to_le32 (sec.type_specific.stream_extension.file_size); + node.have_stream = 1; + break; + case 0xc1: + grub_memcpy (unibuf + slots * 15, + sec.type_specific.file_name.str, 30); + slots++; + break; + default: + grub_printf ("unknown secondary type 0x%02x\n", sec.entry_type); + } + } + + if (i != nsec) + { + offset -= sizeof (dir); + continue; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf, + slots * 15) = '\0'; + + if (hook (filename, &node)) + break; + continue; + } + /* Allocation bitmap. */ + if (dir.entry_type == 0x81) + continue; + /* Upcase table. */ + if (dir.entry_type == 0x82) + continue; + /* Volume label. */ + if (dir.entry_type == 0x83) + continue; + grub_printf ("unknown primary type 0x%02x\n", dir.entry_type); + } + grub_free (filename); + grub_free (unibuf); + + return grub_errno; +} + +#else + static grub_err_t grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, int (*hook) (const char *filename, struct grub_fat_dir_entry *dir)) { struct grub_fat_dir_entry dir; - char *filename, *filep = 0; + char *filename; + char *filep = 0; grub_uint16_t *unibuf; int slot = -1, slots = -1; int checksum = -1; @@ -498,10 +756,11 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, offset += sizeof (dir); /* Read a directory entry. */ - if ((grub_fat_read_data (disk, data, 0, + if (grub_fat_read_data (disk, data, 0, offset, sizeof (dir), (char *) &dir) - != sizeof (dir) || dir.name[0] == 0)) + != sizeof (dir) || dir.name[0] == 0) break; + /* Handle long name entries. */ if (dir.attr == GRUB_FAT_ATTR_LONG_NAME) { @@ -586,7 +845,6 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, filep++; } *filep = '\0'; - if (hook (filename, &dir)) break; } @@ -596,7 +854,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, return grub_errno; } - +#endif /* Find the underlying directory or file in PATH and return the next path. If there is no next path or an error occurs, return NULL. @@ -611,8 +869,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, int call_hook; int found = 0; - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) + auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir); + int iter_hook (const char *filename, grub_fat_dir_node_t *dir) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -620,8 +878,13 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY); info.case_insensitive = 1; +#ifdef MODE_EXFAT + if (!dir->have_stream) + return 0; +#else if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID) return 0; +#endif if (*dirname == '\0' && call_hook) return hook (filename, &info); @@ -629,9 +892,14 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, { found = 1; data->attr = dir->attr; +#ifdef MODE_EXFAT + data->file_size = dir->file_size; + data->file_cluster = dir->first_cluster; +#else data->file_size = grub_le_to_cpu32 (dir->file_size); data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16) | grub_le_to_cpu16 (dir->first_cluster_low)); +#endif data->cur_cluster_num = ~0U; if (call_hook) @@ -781,14 +1049,61 @@ grub_fat_close (grub_file_t file) return grub_errno; } +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_label (grub_device_t device, char **label) +{ + struct grub_fat_dir_entry dir; + grub_ssize_t offset = -sizeof(dir); + struct grub_fat_data *data; + grub_disk_t disk = device->disk; + + data = grub_fat_mount (disk); + if (! data) + return grub_errno; + + while (1) + { + offset += sizeof (dir); + + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + /* Volume label. */ + if (dir.entry_type == 0x83) + { + grub_size_t chc; + *label = grub_malloc (11 * 4 + 1); + if (!*label) + return grub_errno; + chc = dir.type_specific.volume_label.character_count; + if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) + chc = ARRAY_SIZE (dir.type_specific.volume_label.str); + *grub_utf16_to_utf8 ((grub_uint8_t *) *label, + dir.type_specific.volume_label.str, chc) = '\0'; + } + } + + return grub_errno; +} + +#else + static grub_err_t grub_fat_label (grub_device_t device, char **label) { struct grub_fat_data *data; grub_disk_t disk = device->disk; - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) + auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir); + int iter_hook (const char *filename, grub_fat_dir_node_t *dir) { if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID) { @@ -823,6 +1138,8 @@ grub_fat_label (grub_device_t device, char **label) return grub_errno; } +#endif + static grub_err_t grub_fat_uuid (grub_device_t device, char **uuid) { @@ -850,7 +1167,11 @@ grub_fat_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_fat_fs = { +#ifdef MODE_EXFAT + .name = "exfat", +#else .name = "fat", +#endif .dir = grub_fat_dir, .open = grub_fat_open, .read = grub_fat_read, @@ -858,18 +1179,30 @@ static struct grub_fs grub_fat_fs = .label = grub_fat_label, .uuid = grub_fat_uuid, #ifdef GRUB_UTIL +#ifdef MODE_EXFAT + /* ExFAT BPB is 30 larger than FAT32 one. */ + .reserved_first_sector = 0, +#else .reserved_first_sector = 1, +#endif #endif .next = 0 }; +#ifdef MODE_EXFAT +GRUB_MOD_INIT(exfat) +#else GRUB_MOD_INIT(fat) +#endif { grub_fs_register (&grub_fat_fs); my_mod = mod; } - +#ifdef MODE_EXFAT +GRUB_MOD_FINI(exfat) +#else GRUB_MOD_FINI(fat) +#endif { grub_fs_unregister (&grub_fat_fs); } From b6929f5ef598a6d76129fc1915a87bdcf7c62fb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 20:38:08 +0200 Subject: [PATCH 032/315] Transform exfat printfs into dprintfs --- grub-core/fs/fat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 5f7a58571..49bb3a599 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -686,7 +686,8 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, slots++; break; default: - grub_printf ("unknown secondary type 0x%02x\n", sec.entry_type); + grub_dprintf ("exfat", "unknown secondary type 0x%02x\n", + sec.entry_type); } } @@ -712,7 +713,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, /* Volume label. */ if (dir.entry_type == 0x83) continue; - grub_printf ("unknown primary type 0x%02x\n", dir.entry_type); + grub_dprintf ("exfat", "unknown primary type 0x%02x\n", dir.entry_type); } grub_free (filename); grub_free (unibuf); From 2a861f38a7f0b17ada0057b139f9ad6f63aad24f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 14 Apr 2011 20:27:27 +0100 Subject: [PATCH 033/315] Tell FUSE to run single-threaded, since GRUB code is not thread-safe. Fixes Ubuntu bug #756297. --- util/grub-mount.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index efada771a..434772eec 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -450,9 +450,12 @@ main (int argc, char *argv[]) grub_util_init_nls (); - fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); fuse_args[fuse_argc] = xstrdup (argv[0]); fuse_argc++; + /* Run single-threaded. */ + fuse_args[fuse_argc] = xstrdup ("-s"); + fuse_argc++; argp_parse (&argp, argc, argv, 0, 0, 0); From 338c7fab9be66bc5aa6cf093539a0aafa4010b83 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 11 Jun 2011 16:57:19 +0200 Subject: [PATCH 034/315] fix grub-mount buildability on GNU/kFreeBSD --- Makefile.util.def | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index cd37d0d65..313339adc 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -223,7 +223,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse'; condition = COND_GRUB_MOUNT; }; diff --git a/configure.ac b/configure.ac index d1eaa0c84..26af7e7c3 100644 --- a/configure.ac +++ b/configure.ac @@ -871,7 +871,7 @@ fi if test x"$grub_mount_excuse" = x ; then # Check for fuse headers. SAVED_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26" AC_CHECK_HEADERS([fuse/fuse.h], [], [grub_mount_excuse=["need FUSE headers"]]) CPPFLAGS="$SAVED_CPPFLAGS" From 1f1a380be9ba10bf904240106b3bbb274c11e65a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:39:31 +0200 Subject: [PATCH 035/315] Import minilzo library for LZO decompression support. * grub-core/lib/minilzo/lzoconf.h: New file. * grub-core/lib/minilzo/lzodefs.h: Likewise. * grub-core/lib/minilzo/minilzo.c: Likewise. * grub-core/lib/minilzo/minilzo.h: Likewise. * include/grub/types.h (GRUB_UCHAR_MAX): New define. (GRUB_USHRT_MAX): Likewise. (GRUB_UINT_MAX): Likewise. * grub-core/lib/posix_wrap/limits.h (USHRT_MAX): New define. (UINT_MAX): Likewise. (CHAR_BIT): Likewise. * grub-core/lib/posix_wrap/sys/types.h (ULONG_MAX): Moved to grub-core/lib/posix_wrap/limits.h (UCHAR_MAX): Likewise. --- ChangeLog.lzo | 18 + grub-core/lib/minilzo/lzoconf.h | 446 +++ grub-core/lib/minilzo/lzodefs.h | 1852 +++++++++++ grub-core/lib/minilzo/minilzo.c | 4562 ++++++++++++++++++++++++++ grub-core/lib/minilzo/minilzo.h | 109 + grub-core/lib/posix_wrap/limits.h | 31 + grub-core/lib/posix_wrap/sys/types.h | 3 - include/grub/types.h | 4 + 8 files changed, 7022 insertions(+), 3 deletions(-) create mode 100644 ChangeLog.lzo create mode 100644 grub-core/lib/minilzo/lzoconf.h create mode 100644 grub-core/lib/minilzo/lzodefs.h create mode 100644 grub-core/lib/minilzo/minilzo.c create mode 100644 grub-core/lib/minilzo/minilzo.h diff --git a/ChangeLog.lzo b/ChangeLog.lzo new file mode 100644 index 000000000..6f5191db2 --- /dev/null +++ b/ChangeLog.lzo @@ -0,0 +1,18 @@ +2011-08-14 Szymon Janc + + Import minilzo library for LZO decompression support. + + * grub-core/lib/minilzo/lzoconf.h: New file. + * grub-core/lib/minilzo/lzodefs.h: Likewise. + * grub-core/lib/minilzo/minilzo.c: Likewise. + * grub-core/lib/minilzo/minilzo.h: Likewise. + * include/grub/types.h (GRUB_UCHAR_MAX): New define. + (GRUB_USHRT_MAX): Likewise. + (GRUB_UINT_MAX): Likewise. + * grub-core/lib/posix_wrap/limits.h (USHRT_MAX): New define. + (UINT_MAX): Likewise. + (CHAR_BIT): Likewise. + * grub-core/lib/posix_wrap/sys/types.h (ULONG_MAX): Moved to + grub-core/lib/posix_wrap/limits.h + (UCHAR_MAX): Likewise. + diff --git a/grub-core/lib/minilzo/lzoconf.h b/grub-core/lib/minilzo/lzoconf.h new file mode 100644 index 000000000..1d0fe14fc --- /dev/null +++ b/grub-core/lib/minilzo/lzoconf.h @@ -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 + + 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 +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#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: */ diff --git a/grub-core/lib/minilzo/lzodefs.h b/grub-core/lib/minilzo/lzodefs.h new file mode 100644 index 000000000..0e40e332a --- /dev/null +++ b/grub-core/lib/minilzo/lzodefs.h @@ -0,0 +1,1852 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + 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 + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# else +# define LZO_CC_CLANG_CLANG 0x010000L +# endif +# define LZO_CC_CLANG LZO_CC_CLANG_GNUC +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_inline __inline__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# if 0 && defined(__cplusplus) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) +# else +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if (LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif /* already included */ + +/* vim:set ts=4 et: */ diff --git a/grub-core/lib/minilzo/minilzo.c b/grub-core/lib/minilzo/minilzo.c new file mode 100644 index 000000000..25a1f68b3 --- /dev/null +++ b/grub-core/lib/minilzo/minilzo.c @@ -0,0 +1,4562 @@ +/* minilzo.c -- 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 + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO 1 + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# else +# define LZO_CC_CLANG_CLANG 0x010000L +# endif +# define LZO_CC_CLANG LZO_CC_CLANG_GNUC +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_inline __inline__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# if 0 && defined(__cplusplus) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) +# else +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if (LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2050) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H 1 +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H 1 + +#if !defined(__LZO_IN_MINILZO) +#if (LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +# define ACC_LIBC_FREESTANDING 1 +# define ACC_OS_FREESTANDING 1 +#endif +#if (LZO_CFG_NO_UNALIGNED) +# define ACC_CFG_NO_UNALIGNED 1 +#endif +#if (LZO_ARCH_GENERIC) +# define ACC_ARCH_GENERIC 1 +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# define ACC_ABI_NEUTRAL_ENDIAN 1 +#endif +#if (LZO_HAVE_CONFIG_H) +# define ACC_CONFIG_NO_HEADER 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#endif + +#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_BORLANDC && LZO_ARCH_I086) +# pragma option -h +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +# pragma warning(disable: 4514 4710 4711) +#endif + +#if (LZO_CC_SUNPROC) +#if !defined(__cplusplus) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +# pragma error_messages(off,E_STATEMENT_NOT_REACHED) +#endif +#endif + +#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR) +# error "this should not happen - check defines for __huge" +#endif + +#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define ACC_WANT_ACC_INCD_H 1 +# define ACC_WANT_ACC_INCE_H 1 +# define ACC_WANT_ACC_INCI_H 1 +#elif 1 +# include +#else +# define ACC_WANT_ACC_INCD_H 1 +#endif + +#if (LZO_ARCH_I086) +# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT +# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) +# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) +# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) +# define __LZO_UINTPTR_T_IS_POINTER 1 + typedef char* lzo_uintptr_t; +# define lzo_uintptr_t lzo_uintptr_t +# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t size_t +# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long +# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned int +# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long long +# else +# define lzo_uintptr_t size_t +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if (LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memcmp +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memcpy +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memmove +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memset +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if (LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if !defined(__lzo_inline) +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +# define __lzo_noinline /*empty*/ +#endif + +#if (LZO_CFG_PGO) +# undef __acc_likely +# undef __acc_unlikely +# undef __lzo_likely +# undef __lzo_unlikely +# define __acc_likely(e) (e) +# define __acc_unlikely(e) (e) +# define __lzo_likely(e) (e) +# define __lzo_unlikely(e) (e) +#endif + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386 || LZO_ARCH_POWERPC) +# if (LZO_SIZEOF_SHORT == 2) +# define LZO_UNALIGNED_OK_2 1 +# endif +# if (LZO_SIZEOF_INT == 4) +# define LZO_UNALIGNED_OK_4 1 +# endif +#endif +#if 1 && (LZO_ARCH_AMD64) +# if defined(LZO_UINT64_MAX) +# define LZO_UNALIGNED_OK_8 1 +# endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_UNALIGNED_OK_2 +# undef LZO_UNALIGNED_OK_4 +# undef LZO_UNALIGNED_OK_8 +#endif + +#undef UA_GET16 +#undef UA_SET16 +#undef UA_COPY16 +#undef UA_GET32 +#undef UA_SET32 +#undef UA_COPY32 +#undef UA_GET64 +#undef UA_SET64 +#undef UA_COPY64 +#if defined(LZO_UNALIGNED_OK_2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(unsigned short) == 2) +# if 1 && defined(ACC_UA_COPY16) +# define UA_GET16 ACC_UA_GET16 +# define UA_SET16 ACC_UA_SET16 +# define UA_COPY16 ACC_UA_COPY16 +# else +# define UA_GET16(p) (* (__lzo_ua_volatile const lzo_ushortp) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET16(p,v) ((* (__lzo_ua_volatile lzo_ushortp) (__lzo_ua_volatile lzo_voidp) (p)) = (unsigned short) (v)) +# define UA_COPY16(d,s) UA_SET16(d, UA_GET16(s)) +# endif +#endif +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +# if 1 && defined(ACC_UA_COPY32) +# define UA_GET32 ACC_UA_GET32 +# define UA_SET32 ACC_UA_SET32 +# define UA_COPY32 ACC_UA_COPY32 +# else +# define UA_GET32(p) (* (__lzo_ua_volatile const lzo_uint32p) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET32(p,v) ((* (__lzo_ua_volatile lzo_uint32p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint32) (v)) +# define UA_COPY32(d,s) UA_SET32(d, UA_GET32(s)) +# endif +#endif +#if defined(LZO_UNALIGNED_OK_8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64) == 8) +# if 1 && defined(ACC_UA_COPY64) +# define UA_GET64 ACC_UA_GET64 +# define UA_SET64 ACC_UA_SET64 +# define UA_COPY64 ACC_UA_COPY64 +# else +# define UA_GET64(p) (* (__lzo_ua_volatile const lzo_uint64p) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET64(p,v) ((* (__lzo_ua_volatile lzo_uint64p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint64) (v)) +# define UA_COPY64(d,s) UA_SET64(d, UA_GET64(s)) +# endif +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(lzo_uintptr_t) +# if (__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# else +# define lzo_uintptr_t acc_uintptr_t +# ifdef __ACC_INTPTR_T_IS_POINTER +# define __LZO_UINTPTR_T_IS_POINTER 1 +# endif +# endif +#endif + +#if (LZO_ARCH_I086) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#elif (LZO_MM_PVP) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) +#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; +#if defined(LZO_UINT64_MAX) + lzo_int64 a_lzo_int64; + lzo_uint64 a_lzo_uint64; +#endif + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef LZO_DETERMINISTIC +#define LZO_DETERMINISTIC 1 +#endif + +#ifndef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 1 +#if 0 && (LZO_ARCH_I086) +# undef LZO_DICT_USE_PTR +# define LZO_DICT_USE_PTR 0 +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) + p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#elif (LZO_MM_PVP) + p = (lzo_uintptr_t) (ptr); + p = (p << 3) | (p >> 61); +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if defined(__LZO_UINTPTR_T_IS_POINTER) + size_t n = (size_t) ptr; + n = (((n + size - 1) / size) * size) - n; +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +static const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ +#if (LZO_OS_DOS16 && LZO_CC_TURBOC) + return (lzo_voidp) __lzo_copyright; +#else + return (const lzo_bytep) __lzo_copyright; +#endif +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) + const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) + lzo_hbyte_p p = (lzo_hbyte_p) s; + if __lzo_likely(len > 0) do + *p++ = (unsigned char) c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, c, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_INIT) + +#if !defined(__LZO_IN_MINILZO) + +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) + ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) +#if defined(LZO_UINT64_MAX) + ACCCHK_ASSERT(sizeof(lzo_uint64) == 8) + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int64) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint64) +#endif + +#if !defined(__LZO_UINTPTR_T_IS_POINTER) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) + ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + +#endif +#undef ACCCHK_ASSERT + +#if 0 +#define WANT_lzo_bitops_clz32 1 +#define WANT_lzo_bitops_clz64 1 +#endif +#define WANT_lzo_bitops_ctz32 1 +#define WANT_lzo_bitops_ctz64 1 + +#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#include +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 +#pragma intrinsic(_BitScanReverse) +static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanReverse(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz32 lzo_bitops_clz32 +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 +#pragma intrinsic(_BitScanReverse64) +static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanReverse64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz64 lzo_bitops_clz64 +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#pragma intrinsic(_BitScanForward) +static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanForward(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz32 lzo_bitops_ctz32 +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#pragma intrinsic(_BitScanForward64) +static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanForward64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz64 lzo_bitops_ctz64 +#endif + +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) +#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) +#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) +#endif +#endif + +#if 0 +#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) +#else +static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) +{ + return (lzo_voidp) ((lzo_bytep) ptr + off); +} +#endif + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + union { + lzo_xint a[2]; unsigned char b[2*LZO_MAX(8,sizeof(lzo_xint))]; +#if defined(LZO_UNALIGNED_OK_8) + lzo_uint64 c[2]; +#endif + unsigned short x[2]; lzo_uint32 y[2]; lzo_uint z[2]; + } u; + lzo_voidp p; + + u.a[0] = u.a[1] = 0; + p = u2p(&u, 0); + r &= ((* (lzo_bytep) p) == 0); +#if !defined(LZO_CFG_NO_CONFIG_CHECK) +#if defined(LZO_ABI_BIG_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if defined(LZO_ABI_LITTLE_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[0] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if defined(LZO_UNALIGNED_OK_2) + u.a[0] = u.a[1] = 0; + u.b[0] = 1; u.b[sizeof(unsigned short) + 1] = 2; + p = u2p(&u, 1); + r &= ((* (lzo_ushortp) p) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_4) + u.a[0] = u.a[1] = 0; + u.b[0] = 3; u.b[sizeof(lzo_uint32) + 1] = 4; + p = u2p(&u, 1); + r &= ((* (lzo_uint32p) p) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_8) + u.c[0] = u.c[1] = 0; + u.b[0] = 5; u.b[sizeof(lzo_uint64) + 1] = 6; + p = u2p(&u, 1); + r &= ((* (lzo_uint64p) p) == 0); +#endif +#if defined(lzo_bitops_clz32) + { unsigned i; lzo_uint32 v = 1; + for (i = 0; i < 31; i++, v <<= 1) + r &= lzo_bitops_clz32(v) == 31 - i; + } +#endif +#if defined(lzo_bitops_clz64) + { unsigned i; lzo_uint64 v = 1; + for (i = 0; i < 63; i++, v <<= 1) + r &= lzo_bitops_clz64(v) == 63 - i; + } +#endif +#if defined(lzo_bitops_ctz32) + { unsigned i; lzo_uint32 v = 1; + for (i = 0; i < 31; i++, v <<= 1) + r &= lzo_bitops_ctz32(v) == i; + } +#endif +#if defined(lzo_bitops_ctz64) + { unsigned i; lzo_uint64 v = 1; + for (i = 0; i < 63; i++, v <<= 1) + r &= lzo_bitops_ctz64(v) == i; + } +#endif +#endif + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT +#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef ACCCHK_ASSERT + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#endif + +#define LZO1X 1 +#define LZO_EOF_CODE 1 +#define M2_MAX_OFFSET 0x0800 + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#if 1 && defined(UA_GET32) +#undef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 0 +#undef lzo_dict_t +#define lzo_dict_t unsigned short +#endif + +#define LZO_NEED_DICT_H 1 +#ifndef D_BITS +#define D_BITS 14 +#endif +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#if 1 +#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) +#else +#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) +#endif + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H 1 + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X 1 +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#ifndef LZO_EOF_CODE +#define LZO_EOF_CODE 1 +#endif +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 6 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 6 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +#if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM) +static void __attribute__((__unused__)) +#else +static void +#endif +DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if (LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if (LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) + +#ifndef DO_COMPRESS +#define DO_COMPRESS lzo1x_1_compress +#endif + +#if 1 && defined(DO_COMPRESS) && !defined(do_compress) +# define do_compress LZO_CPP_ECONCAT2(DO_COMPRESS,_core) +#endif + +#if defined(UA_GET64) +# define WANT_lzo_bitops_ctz64 1 +#elif defined(UA_GET32) +# define WANT_lzo_bitops_ctz32 1 +#endif + +#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#include +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 +#pragma intrinsic(_BitScanReverse) +static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanReverse(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz32 lzo_bitops_clz32 +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 +#pragma intrinsic(_BitScanReverse64) +static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanReverse64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz64 lzo_bitops_clz64 +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#pragma intrinsic(_BitScanForward) +static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanForward(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz32 lzo_bitops_ctz32 +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#pragma intrinsic(_BitScanForward64) +static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanForward64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz64 lzo_bitops_ctz64 +#endif + +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) +#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) +#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) +#endif +#endif + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_uint ti, lzo_voidp wrkmem) +{ + register const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - 20; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip - ti; + + ip += ti < 4 ? 4 - ti : 0; + for (;;) + { + const lzo_bytep m_pos; +#if !(LZO_DETERMINISTIC) + LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); + lzo_uint m_len; + lzo_uint dindex; +next: + if __lzo_unlikely(ip >= ip_end) + break; + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if defined(UA_GET32) + if (UA_GET32(m_pos) != UA_GET32(ip)) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) +#endif + { +literal: + UPDATE_I(dict,0,dindex,ip,in); + ip += 1 + ((ip - ii) >> 5); + continue; + } + UPDATE_I(dict,0,dindex,ip,in); +#else + lzo_uint m_off; + lzo_uint m_len; + { + lzo_uint32 dv; + lzo_uint dindex; +literal: + ip += 1 + ((ip - ii) >> 5); +next: + if __lzo_unlikely(ip >= ip_end) + break; + dv = UA_GET32(ip); + dindex = DINDEX(dv,ip); + GINDEX(m_off,m_pos,in+dict,dindex,in); + UPDATE_I(dict,0,dindex,ip,in); + if __lzo_unlikely(dv != UA_GET32(m_pos)) + goto literal; + } +#endif + + { + register lzo_uint t = pd(ip,ii); + if (t != 0) + { + if (t <= 3) + { + op[-2] |= LZO_BYTE(t); +#if defined(UA_COPY32) + UA_COPY32(op, ii); + op += t; +#else + { do *op++ = *ii++; while (--t > 0); } +#endif + } +#if defined(UA_COPY32) || defined(UA_COPY64) + else if (t <= 16) + { + *op++ = LZO_BYTE(t - 3); +#if defined(UA_COPY64) + UA_COPY64(op, ii); + UA_COPY64(op+8, ii+8); +#else + UA_COPY32(op, ii); + UA_COPY32(op+4, ii+4); + UA_COPY32(op+8, ii+8); + UA_COPY32(op+12, ii+12); +#endif + op += t; + } +#endif + else + { + if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + *op++ = 0; + while __lzo_unlikely(tt > 255) + { + tt -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } +#if defined(UA_COPY32) || defined(UA_COPY64) + do { +#if defined(UA_COPY64) + UA_COPY64(op, ii); + UA_COPY64(op+8, ii+8); +#else + UA_COPY32(op, ii); + UA_COPY32(op+4, ii+4); + UA_COPY32(op+8, ii+8); + UA_COPY32(op+12, ii+12); +#endif + op += 16; ii += 16; t -= 16; + } while (t >= 16); if (t > 0) +#endif + { do *op++ = *ii++; while (--t > 0); } + } + } + } + m_len = 4; + { +#if defined(UA_GET64) + lzo_uint64 v; + v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 8; + v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz64) + m_len += lzo_bitops_ctz64(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#elif defined(UA_GET32) + lzo_uint32 v; + v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 4; + v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz32) + m_len += lzo_bitops_ctz32(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#else + if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { + do { + m_len += 1; + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (ip[m_len] == m_pos[m_len]); + } +#endif + } +m_len_done: + m_off = pd(ip,m_pos); + ip += m_len; + ii = ip; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + else + { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + goto next; + } + + *out_len = pd(op, out); + return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_bytep ip = in; + lzo_bytep op = out; + lzo_uint l = in_len; + lzo_uint t = 0; + + while (l > 20) + { + lzo_uint ll = l; + lzo_uintptr_t ll_end; +#if 0 || (LZO_DETERMINISTIC) + ll = LZO_MIN(ll, 49152); +#endif + ll_end = (lzo_uintptr_t)ip + ll; + if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) + break; +#if (LZO_DETERMINISTIC) + lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); +#endif + t = do_compress(ip,ll,op,out_len,t,wrkmem); + ip += ll; + op += *out_len; + l -= ll; + } + t += l; + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + t += 3; + if (t >= 8) do + { + UA_COPY64(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY32(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY64(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN 1 +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + t += 3; + if (t >= 8) do + { + UA_COPY64(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY32(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY64(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ + diff --git a/grub-core/lib/minilzo/minilzo.h b/grub-core/lib/minilzo/minilzo.h new file mode 100644 index 000000000..74fefa9fe --- /dev/null +++ b/grub-core/lib/minilzo/minilzo.h @@ -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 + + 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 */ + diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h index e69de29bb..fe8523e68 100644 --- a/grub-core/lib/posix_wrap/limits.h +++ b/grub-core/lib/posix_wrap/limits.h @@ -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 . + */ + +#ifndef GRUB_POSIX_LIMITS_H +#define GRUB_POSIX_LIMITS_H + +#include + +#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 diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 69e49509e..0c58d6c44 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -24,9 +24,6 @@ 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; diff --git a/include/grub/types.h b/include/grub/types.h index 4fd7a3a4b..32d255d40 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -116,6 +116,10 @@ typedef grub_int32_t grub_ssize_t; # define PRIuGRUB_SIZE "u" #endif +#define GRUB_UCHAR_MAX 0xFF +#define GRUB_USHRT_MAX 65535 +#define GRUB_UINT_MAX 4294967295U + #if GRUB_CPU_SIZEOF_LONG == 8 # define GRUB_ULONG_MAX 18446744073709551615UL # define GRUB_LONG_MAX 9223372036854775807L From b2d7e331e2b5cb9899a13e5e105e96d2632da995 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:41:19 +0200 Subject: [PATCH 036/315] Add helper functions for easier unaligned memory access. * include/grub/types.h (grub_get_unaligned16): New function. (grub_get_unaligned32): Likewise. (grub_get_unaligned64): Likewise. --- ChangeLog.lzo | 8 ++++++++ include/grub/types.h | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 6f5191db2..701715747 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,11 @@ +2001-08-14 Szymon Janc + + Add helper functions for easier unaligned memory access. + + * include/grub/types.h (grub_get_unaligned16): New function. + (grub_get_unaligned32): Likewise. + (grub_get_unaligned64): Likewise. + 2011-08-14 Szymon Janc Import minilzo library for LZO decompression support. diff --git a/include/grub/types.h b/include/grub/types.h index 32d255d40..f057dd3d3 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -222,4 +222,31 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x)) #endif /* ! WORDS_BIGENDIAN */ +static inline grub_uint16_t grub_get_unaligned16(void *ptr) +{ + struct + { + grub_uint16_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + +static inline grub_uint32_t grub_get_unaligned32(void *ptr) +{ + struct + { + grub_uint32_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + +static inline grub_uint64_t grub_get_unaligned64(void *ptr) +{ + struct + { + grub_uint64_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + #endif /* ! GRUB_TYPES_HEADER */ From b6085f323611098c84177e90701809b6a8c5dcaf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:42:53 +0200 Subject: [PATCH 037/315] * grub-core/fs/btrfs.c: Some code style fixes. --- ChangeLog.lzo | 4 + grub-core/fs/btrfs.c | 187 +++++++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 97 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 701715747..0a9d852a4 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,7 @@ +2011-08-14 Szymon Janc + + * grub-core/fs/btrfs.c: Some code style fixes. + 2001-08-14 Szymon Janc Add helper functions for easier unaligned memory access. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 6470c9819..1336c8f02 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -41,7 +41,7 @@ struct grub_btrfs_device } __attribute__ ((packed)); struct grub_btrfs_superblock -{ +{ grub_btrfs_checksum_t checksum; grub_btrfs_uuid_t uuid; grub_uint8_t dummy[0x10]; @@ -160,7 +160,8 @@ struct grub_btrfs_leaf_descriptor { unsigned depth; unsigned allocated; - struct { + struct + { grub_disk_addr_t addr; unsigned iter; unsigned maxiter; @@ -179,7 +180,7 @@ struct grub_btrfs_time { grub_int64_t sec; grub_uint32_t nanosec; -} __attribute__ ((aligned(4))); +} __attribute__ ((aligned (4))); struct grub_btrfs_inode { @@ -219,8 +220,8 @@ struct grub_btrfs_extent_data #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, - 256 * 1048576 * 2, - 1048576ULL * 1048576ULL * 2 }; + 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 +}; static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, @@ -283,7 +284,7 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc) } static grub_err_t -save_ref (struct grub_btrfs_leaf_descriptor *desc, +save_ref (struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t addr, unsigned i, unsigned m, int l) { desc->depth++; @@ -307,7 +308,7 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, static int next (struct grub_btrfs_data *data, struct grub_btrfs_leaf_descriptor *desc, - grub_disk_addr_t *outaddr, grub_size_t *outsize, + grub_disk_addr_t * outaddr, grub_size_t * outsize, struct grub_btrfs_key *key_out) { grub_err_t err; @@ -316,8 +317,8 @@ next (struct grub_btrfs_data *data, for (; desc->depth > 0; desc->depth--) { desc->data[desc->depth - 1].iter++; - if (desc->data[desc->depth - 1].iter - < desc->data[desc->depth - 1].maxiter) + if (desc->data[desc->depth - 1].iter < + desc->data[desc->depth - 1].maxiter) break; } if (desc->depth == 0) @@ -330,17 +331,17 @@ next (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter * sizeof (node) + sizeof (struct btrfs_header) - + desc->data[desc->depth - 1].addr, &node, - sizeof (node)); + + desc->data[desc->depth - 1].addr, + &node, sizeof (node)); if (err) return -err; - err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head, - sizeof (head)); + err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), + &head, sizeof (head)); if (err) return -err; - save_ref (desc, grub_le_to_cpu64 (node.addr), 0, + save_ref (desc, grub_le_to_cpu64 (node.addr), 0, grub_le_to_cpu32 (head.nitems), !head.level); } err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter @@ -354,15 +355,15 @@ next (struct grub_btrfs_data *data, *outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header) + grub_le_to_cpu32 (leaf.offset); *key_out = leaf.key; - return 1; + return 1; } static grub_err_t lower_bound (struct grub_btrfs_data *data, - const struct grub_btrfs_key *key_in, + const struct grub_btrfs_key *key_in, struct grub_btrfs_key *key_out, grub_disk_addr_t root, - grub_disk_addr_t *outaddr, grub_size_t *outsize, + grub_disk_addr_t * outaddr, grub_size_t * outsize, struct grub_btrfs_leaf_descriptor *desc) { grub_disk_addr_t addr = root; @@ -410,8 +411,9 @@ lower_bound (struct grub_btrfs_data *data, grub_dprintf ("btrfs", "internal node (depth %d) %" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", depth, - node.key.object_id, node.key.type, node.key.offset); - + node.key.object_id, node.key.type, + node.key.offset); + if (key_cmp (&node.key, key_in) == 0) { err = GRUB_ERR_NONE; @@ -433,7 +435,7 @@ lower_bound (struct grub_btrfs_data *data, err = GRUB_ERR_NONE; if (desc) err = save_ref (desc, addr - sizeof (head), i - 1, - grub_le_to_cpu32 (head.nitems), 0); + grub_le_to_cpu32 (head.nitems), 0); if (err) return err; addr = grub_le_to_cpu64 (node_last.addr); @@ -457,7 +459,7 @@ lower_bound (struct grub_btrfs_data *data, &leaf, sizeof (leaf)); if (err) return err; - + grub_dprintf ("btrfs", "leaf (depth %d) %" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", depth, @@ -465,31 +467,31 @@ lower_bound (struct grub_btrfs_data *data, if (key_cmp (&leaf.key, key_in) == 0) { - grub_memcpy (key_out, &leaf.key, sizeof(*key_out)); + grub_memcpy (key_out, &leaf.key, sizeof (*key_out)); *outsize = grub_le_to_cpu32 (leaf.size); *outaddr = addr + grub_le_to_cpu32 (leaf.offset); if (desc) return save_ref (desc, addr - sizeof (head), i, grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } - + if (key_cmp (&leaf.key, key_in) > 0) break; - + have_last = 1; leaf_last = leaf; } if (have_last) { - grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out)); + grub_memcpy (key_out, &leaf_last.key, sizeof (*key_out)); *outsize = grub_le_to_cpu32 (leaf_last.size); *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); if (desc) return save_ref (desc, addr - sizeof (head), i - 1, grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } *outsize = 0; *outaddr = 0; @@ -503,8 +505,7 @@ lower_bound (struct grub_btrfs_data *data, } static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id, - int do_rescan) +find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) { grub_device_t dev_found = NULL; auto int hook (const char *name); @@ -540,7 +541,7 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, grub_device_close (dev); return 0; } - + dev_found = dev; return 1; } @@ -579,17 +580,16 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, } static grub_err_t -grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_addr_t addr, +grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size) { while (size > 0) { grub_uint8_t *ptr; struct grub_btrfs_key *key; - struct grub_btrfs_chunk_item *chunk; + struct grub_btrfs_chunk_item *chunk; grub_uint64_t csize; - grub_err_t err = 0; + grub_err_t err = 0; struct grub_btrfs_key key_out; int challoc = 0; grub_device_t dev; @@ -601,20 +601,20 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, addr); for (ptr = data->sblock.bootstrap_mapping; ptr < data->sblock.bootstrap_mapping - + sizeof (data->sblock.bootstrap_mapping) - - sizeof (struct grub_btrfs_key); - ) + + sizeof (data->sblock.bootstrap_mapping) + - sizeof (struct grub_btrfs_key);) { key = (struct grub_btrfs_key *) ptr; if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK) break; chunk = (struct grub_btrfs_chunk_item *) (key + 1); - grub_dprintf ("btrfs", "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", + grub_dprintf ("btrfs", + "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", grub_le_to_cpu64 (key->offset), grub_le_to_cpu64 (chunk->size)); if (grub_le_to_cpu64 (key->offset) <= addr - && addr < grub_le_to_cpu64 (key->offset) - + grub_le_to_cpu64 (chunk->size)) + && addr < + grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size)) goto chunk_found; ptr += sizeof (*key) + sizeof (*chunk) + sizeof (struct grub_btrfs_chunk_stripe) @@ -704,11 +704,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); - + high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes), &stripen); - stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) - * high; + stripe_offset = + low + grub_le_to_cpu64 (chunk->stripe_length) * high; csize = grub_le_to_cpu64 (chunk->stripe_length) - low; break; } @@ -719,7 +719,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); - + high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nsubstripes), &stripen); @@ -759,7 +759,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, paddr = stripe->offset + stripe_offset; grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T " maps to 0x%" PRIxGRUB_UINT64_T "\n", grub_le_to_cpu64 (key->offset), @@ -769,7 +770,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_le_to_cpu64 (chunk->stripe_length), stripen, stripe->offset); grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, + " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, addr); dev = find_device (data, stripe->device_id, j); @@ -815,7 +816,7 @@ grub_btrfs_mount (grub_device_t dev) } data = grub_zalloc (sizeof (*data)); - if (! data) + if (!data) return NULL; err = read_sblock (dev->disk, &data->sblock); @@ -866,8 +867,7 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; key_in.offset = 0; - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, NULL); + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL); if (err) return err; if (num != key_out.object_id @@ -917,19 +917,17 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (!data->extent) return grub_errno; - err = grub_btrfs_read_logical (data, elemaddr, - data->extent, elemsize); + err = grub_btrfs_read_logical (data, elemaddr, data->extent, + elemsize); if (err) return err; - data->extend = data->extstart - + grub_le_to_cpu64 (data->extent->size); + data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) &data->extent + elemsize - >= (char *) &data->extent->filled - + sizeof (data->extent->filled)) - data->extend = data->extstart - + grub_le_to_cpu64 (data->extent->filled); + && (char *) &data->extent + elemsize >= + (char *) &data->extent->filled + sizeof (data->extent->filled)) + data->extend = + data->extstart + grub_le_to_cpu64 (data->extent->filled); grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" PRIxGRUB_UINT64_T " (0x%" @@ -966,8 +964,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (data->extent->encoding) { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "encoding not supported"); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported"); return -1; } @@ -1008,8 +1005,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_free (tmp); return -1; } - if (grub_zlib_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), + if (grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), buf, csize) != (grub_ssize_t) csize) { grub_free (tmp); @@ -1021,14 +1018,13 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) - + extoff, - buf, csize); + + extoff, buf, csize); if (err) return -1; break; default: grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x", data->extent->type); + "unsupported extent type 0x%x", data->extent->type); return -1; } buf += csize; @@ -1041,7 +1037,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, static grub_err_t find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, - grub_uint64_t *tree, grub_uint8_t *type) + grub_uint64_t * tree, grub_uint8_t * type) { const char *slash = path; grub_err_t err; @@ -1096,9 +1092,9 @@ find_path (struct grub_btrfs_data *data, key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); - - err = lower_bound (data, key, &key_out, *tree, - &elemaddr, &elemsize, NULL); + + err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, + NULL); if (err) { grub_free (direl); @@ -1140,7 +1136,7 @@ find_path (struct grub_btrfs_data *data, for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; + < (grub_ssize_t) elemsize; cdirel = (void *) ((grub_uint8_t *) (direl + 1) + grub_le_to_cpu16 (cdirel->n) + grub_le_to_cpu16 (cdirel->m))) @@ -1174,7 +1170,7 @@ find_path (struct grub_btrfs_data *data, return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); } - + err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, *tree); if (err) @@ -1205,7 +1201,7 @@ find_path (struct grub_btrfs_data *data, grub_free (tmp); return grub_errno; } - grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, + grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, grub_strlen (path) + 1); grub_free (path_alloc); grub_free (origpath); @@ -1247,8 +1243,7 @@ find_path (struct grub_btrfs_data *data, grub_free (origpath); return err; } - err = grub_btrfs_read_logical (data, elemaddr, - &ri, sizeof (ri)); + err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri)); if (err) { grub_free (direl); @@ -1279,7 +1274,7 @@ find_path (struct grub_btrfs_data *data, grub_free (path_alloc); grub_free (origpath); grub_free (direl); - return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", + return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", cdirel->key.type); } } @@ -1290,8 +1285,8 @@ find_path (struct grub_btrfs_data *data, static grub_err_t grub_btrfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) + int (*hook) (const char *filename, + const struct grub_dirhook_info * info)) { struct grub_btrfs_data *data = grub_btrfs_mount (device); struct grub_btrfs_key key_in, key_out; @@ -1312,10 +1307,9 @@ grub_btrfs_dir (grub_device_t device, const char *path, if (err) return err; if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, &desc); + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc); if (err) return err; if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM @@ -1355,7 +1349,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; + < (grub_ssize_t) elemsize; cdirel = (void *) ((grub_uint8_t *) (direl + 1) + grub_le_to_cpu16 (cdirel->n) + grub_le_to_cpu16 (cdirel->m))) @@ -1384,7 +1378,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, } while (r > 0); - out: +out: grub_free (direl); free_iterator (&desc); @@ -1456,7 +1450,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) *uuid = NULL; data = grub_btrfs_mount (device); - if (! data) + if (!data) return grub_errno; *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", @@ -1482,7 +1476,7 @@ grub_btrfs_label (grub_device_t device, char **label) *label = NULL; data = grub_btrfs_mount (device); - if (! data) + if (!data) return grub_errno; *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); @@ -1492,26 +1486,25 @@ grub_btrfs_label (grub_device_t device, char **label) return grub_errno; } -static struct grub_fs grub_btrfs_fs = - { - .name = "btrfs", - .dir = grub_btrfs_dir, - .open = grub_btrfs_open, - .read = grub_btrfs_read, - .close = grub_btrfs_close, - .uuid = grub_btrfs_uuid, - .label = grub_btrfs_label, +static struct grub_fs grub_btrfs_fs = { + .name = "btrfs", + .dir = grub_btrfs_dir, + .open = grub_btrfs_open, + .read = grub_btrfs_read, + .close = grub_btrfs_close, + .uuid = grub_btrfs_uuid, + .label = grub_btrfs_label, #ifdef GRUB_UTIL - .reserved_first_sector = 1, + .reserved_first_sector = 1, #endif - }; +}; -GRUB_MOD_INIT(btrfs) +GRUB_MOD_INIT (btrfs) { grub_fs_register (&grub_btrfs_fs); } -GRUB_MOD_FINI(btrfs) +GRUB_MOD_FINI (btrfs) { grub_fs_unregister (&grub_btrfs_fs); } From 095f077e6db33fefb9c9eae6fcbb47b2bef577f8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:46:05 +0200 Subject: [PATCH 038/315] Add support for LZO compression in btrfs. * Makefile.util.def (libgrubmods.a): Add minilzo.c and add required flags to cflags in cppflags. * Makefile.core.def (btrfs): Likewise. * grub-core/fs/btrfs.c: Include minilzo.h. (grub_btrfs_superblock): Add sectorsize, nodesize, leafsize, stripsize and dummy5 field. (GRUB_BTRFS_COMPRESSION_LZO): New define. (grub_btrfs_extent_read): Add support for LZO compression type. --- ChangeLog.lzo | 13 ++++ Makefile.util.def | 3 + grub-core/Makefile.core.def | 3 + grub-core/fs/btrfs.c | 136 ++++++++++++++++++++++++++++++++---- 4 files changed, 143 insertions(+), 12 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 0a9d852a4..c89255389 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,16 @@ +2011-08-14 Szymon Janc + + Add support for LZO compression in btrfs. + + * Makefile.util.def (libgrubmods.a): Add minilzo.c and add required flags + to cflags in cppflags. + * Makefile.core.def (btrfs): Likewise. + * grub-core/fs/btrfs.c: Include minilzo.h. + (grub_btrfs_superblock): Add sectorsize, nodesize, leafsize, stripsize and + dummy5 field. + (GRUB_BTRFS_COMPRESSION_LZO): New define. + (grub_btrfs_extent_read): Add support for LZO compression type. + 2011-08-14 Szymon Janc * grub-core/fs/btrfs.c: Some code style fixes. diff --git a/Makefile.util.def b/Makefile.util.def index d86cb9761..3628e48f6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -33,6 +33,8 @@ library = { library = { name = libgrubmods.a; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(top_srcdir)/grub-core/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; common_nodist = grub_script.tab.c; common_nodist = grub_script.yy.c; @@ -107,6 +109,7 @@ library = { common = grub-core/script/argv.c; common = grub-core/io/gzio.c; common = grub-core/kern/ia64/dl_helper.c; + common = grub-core/lib/minilzo/minilzo.c; }; program = { diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 0924602f3..1ff179c67 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -979,6 +979,9 @@ module = { name = btrfs; common = fs/btrfs.c; common = lib/crc.c; + common = lib/minilzo/minilzo.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; module = { diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 1336c8f02..1d24da3e3 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -26,6 +26,7 @@ #include #include #include +#include "minilzo.h" GRUB_MOD_LICENSE ("GPLv3+"); @@ -51,10 +52,15 @@ struct grub_btrfs_superblock grub_uint64_t chunk_tree; grub_uint8_t dummy2[0x20]; grub_uint64_t root_dir_objectid; - grub_uint8_t dummy3[0x41]; + grub_uint8_t dummy3[0x8]; + grub_uint32_t sectorsize; + grub_uint32_t nodesize; + grub_uint32_t leafsize; + grub_uint32_t stripsize; + grub_uint8_t dummy4[0x29]; struct grub_btrfs_device this_device; char label[0x100]; - grub_uint8_t dummy4[0x100]; + grub_uint8_t dummy5[0x100]; grub_uint8_t bootstrap_mapping[0x800]; } __attribute__ ((packed)); @@ -216,6 +222,7 @@ struct grub_btrfs_extent_data #define GRUB_BTRFS_COMPRESSION_NONE 0 #define GRUB_BTRFS_COMPRESSION_ZLIB 1 +#define GRUB_BTRFS_COMPRESSION_LZO 2 #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 @@ -954,7 +961,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE - && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB) + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB + && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression type 0x%x not supported", @@ -980,6 +988,42 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, != (grub_ssize_t) csize) return -1; } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + { + grub_uint32_t total_size, chunk_size; + unsigned char *obuf; + unsigned char *ibuf = (unsigned char *) data->extent->inl; + lzo_uint ocnt = extoff + csize; + int ret; + + obuf = grub_malloc (extoff + csize); + if (!obuf) + return -1; + + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + + /* Can we have multiple chunks in inline extent? */ + if (chunk_size + (sizeof (grub_uint32_t) * 2) != total_size) + { + grub_free (obuf); + return -1; + } + + ret = lzo1x_decompress_safe (ibuf, chunk_size, obuf, &ocnt, NULL); + + if (ret != LZO_E_OK) + { + grub_free (obuf); + return -1; + } + + grub_memcpy (buf, obuf + extoff, ocnt - extoff); + grub_free (obuf); + } else grub_memcpy (buf, data->extent->inl + extoff, csize); break; @@ -989,9 +1033,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_memset (buf, 0, csize); break; } - if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + + if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) { - char *tmp; + void *tmp; grub_uint64_t zsize; zsize = grub_le_to_cpu64 (data->extent->compressed_size); tmp = grub_malloc (zsize); @@ -1005,16 +1050,83 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_free (tmp); return -1; } - if (grub_zlib_decompress (tmp, zsize, extoff + - grub_le_to_cpu64 (data->extent->offset), - buf, csize) != (grub_ssize_t) csize) + + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) { + grub_ssize_t ret; + + ret = grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + grub_free (tmp); - return -1; + + if (ret != (grub_ssize_t) csize) + return -1; + + break; } - grub_free (tmp); - break; - } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + { + grub_uint32_t total_size, chunk_size, usize = 0; + grub_size_t off = extoff; + unsigned char *chunk, *ibuf = tmp; + char *obuf = buf; + /* XXX Is this correct size from sblock? */ + grub_uint32_t udata_size = grub_le_to_cpu32 (data->sblock.sectorsize); + + chunk = grub_malloc (udata_size); + if (!chunk) + { + grub_free (tmp); + return -1; + } + + /* XXX Use this for some sanity checks while decompressing. */ + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + + /* Jump to first chunk with requested data. */ + while (off >= udata_size) + { + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + ibuf += chunk_size; + off -= udata_size; + } + + while (usize < csize) + { + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + lzo_uint csize2 = udata_size; + int diff; + + ibuf += sizeof (chunk_size); + + if (lzo1x_decompress_safe (ibuf, chunk_size, chunk, &csize2, NULL) != LZO_E_OK) + { + grub_free (tmp); + grub_free (chunk); + return -1; + } + + diff = grub_min (csize2 - off, csize - usize); + + grub_memcpy (obuf, chunk + off, diff); + obuf += diff; + ibuf += chunk_size; + usize += diff; + off = 0; + } + + grub_free (tmp); + grub_free (chunk); + break; + } + } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) From d6beefcfc9d3451fe262b6d57ccc215db8ce5681 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 17 Aug 2011 19:40:25 +0200 Subject: [PATCH 039/315] Add initial support for lzop files decompression. * grub-core/Makefile.core.def (lzopio): New module. * grub-core/io/lzopio.c: New file. * include/grub/file.h (grub_file_filter_id): New compression filter GRUB_FILE_FILTER_LZOPIO. --- ChangeLog.lzo | 9 + grub-core/Makefile.core.def | 8 + grub-core/io/lzopio.c | 527 ++++++++++++++++++++++++++++++++++++ include/grub/file.h | 1 + 4 files changed, 545 insertions(+) create mode 100644 grub-core/io/lzopio.c diff --git a/ChangeLog.lzo b/ChangeLog.lzo index c89255389..782c6b60d 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,12 @@ +2011-08-17 Szymon Janc + + Add initial support for lzop files decompression. + + * grub-core/Makefile.core.def (lzopio): New module. + * grub-core/io/lzopio.c: New file. + * include/grub/file.h (grub_file_filter_id): New compression filter + GRUB_FILE_FILTER_LZOPIO. + 2011-08-14 Szymon Janc Add support for LZO compression in btrfs. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 1ff179c67..67959d861 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1651,6 +1651,14 @@ module = { cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; }; +module = { + name = lzopio; + common = io/lzopio.c; + common = lib/minilzo/minilzo.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; +}; + module = { name = testload; common = commands/testload.c; diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c new file mode 100644 index 000000000..4ccc41a16 --- /dev/null +++ b/grub-core/io/lzopio.c @@ -0,0 +1,527 @@ +/* lzopio.c - decompression support for lzop */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "minilzo.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" +#define LZOP_MAGIC_SIZE 9 +#define CHECK_SIZE 4 +#define NEW_LZO_LIB 0x0940 +#define MIN_HEADER_SIZE 0 +#define MAX_HEADER_SIZE 0 + +/* Header flags - copied from conf.h of LZOP source code. */ +#define F_ADLER32_D 0x00000001L +#define F_ADLER32_C 0x00000002L +#define F_STDIN 0x00000004L +#define F_STDOUT 0x00000008L +#define F_NAME_DEFAULT 0x00000010L +#define F_DOSISH 0x00000020L +#define F_H_EXTRA_FIELD 0x00000040L +#define F_H_GMTDIFF 0x00000080L +#define F_CRC32_D 0x00000100L +#define F_CRC32_C 0x00000200L +#define F_MULTIPART 0x00000400L +#define F_H_FILTER 0x00000800L +#define F_H_CRC32 0x00001000L +#define F_H_PATH 0x00002000L +#define F_MASK 0x00003FFFL + +struct block_header +{ + grub_uint32_t usize; + grub_uint32_t csize; + grub_uint32_t ucheck; + grub_uint32_t ccheck; + unsigned char *cdata; + unsigned char *udata; +}; + +struct grub_lzopio +{ + grub_file_t file; + int ucheck; /* XXX Use gcry to validate checks. */ + int ccheck; + grub_off_t saved_off; /* Rounded down to block boundary. */ + grub_off_t start_block_off; + struct block_header block; +}; + +typedef struct grub_lzopio *grub_lzopio_t; +static struct grub_fs grub_lzopio_fs; + +/* Some helper functions. Memory allocated by those function is free either + * on next read_block_header() or on close() so no risk of leaks. This makes + * those function simpler. */ + +/* Read block header from file, after successful exit file points to + * beginning of block data. */ +static int +read_block_header (struct grub_lzopio *lzopio) +{ + /* Free cached block data if any. */ + grub_free (lzopio->block.udata); + grub_free (lzopio->block.cdata); + lzopio->block.udata = NULL; + lzopio->block.cdata = NULL; + + if (grub_file_read (lzopio->file, &lzopio->block.usize, + sizeof (lzopio->block.usize)) != + sizeof (lzopio->block.usize)) + return -1; + + lzopio->block.usize = grub_be_to_cpu32 (lzopio->block.usize); + + /* Last block has uncompressed data size == 0 and no other fields. */ + if (lzopio->block.usize == 0) + { + if (grub_file_tell (lzopio->file) == grub_file_size (lzopio->file)) + return 0; + else + return -1; + } + + /* Read compressed data block size. */ + if (grub_file_read (lzopio->file, &lzopio->block.csize, + sizeof (lzopio->block.csize)) != + sizeof (lzopio->block.csize)) + return -1; + + lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize); + + /* XXX Handle incompressible data case here rather than in uncompress_block. + * This will allow to handle switch of ccheck/ucheck easier and also + * make uncompress_block() a bit simpler. */ + + /* Read data checks. */ + if (lzopio->ucheck) + { + if (grub_file_read (lzopio->file, &lzopio->block.ucheck, + sizeof (lzopio->block.ucheck)) != + sizeof (lzopio->block.ucheck)) + return -1; + } + + if (lzopio->ccheck) + { + if (grub_file_read (lzopio->file, &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != + sizeof (lzopio->block.ccheck)) + return -1; + } + return 0; +} + +/* Read block data into memory. File must be set to beginning of block data. + * Can't be called on last block. */ +static int +read_block_data (struct grub_lzopio *lzopio) +{ + lzopio->block.cdata = grub_malloc (lzopio->block.csize); + if (!lzopio->block.cdata) + return -1; + + if (grub_file_read (lzopio->file, lzopio->block.cdata, lzopio->block.csize) + != (grub_ssize_t) lzopio->block.csize) + return -1; + + if (lzopio->ccheck) + { + /* XXX Validate data checksum here. */ + } + + return 0; +} + +/* Read block data, uncompressed and also store it in memory. */ +/* XXX Investigate possibility of in-place decompression to reduce memory + * footprint. */ +static int +uncompress_block (struct grub_lzopio *lzopio) +{ + lzo_uint usize = lzopio->block.usize; + + if (read_block_data (lzopio) < 0) + return -1; + + if (lzopio->block.usize > lzopio->block.csize) + { + lzopio->block.udata = grub_malloc (lzopio->block.usize); + if (!lzopio->block.udata) + return -1; + + if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, + lzopio->block.udata, &usize, + NULL) != LZO_E_OK) + return -1; + + if (lzopio->ucheck) + { + /* XXX Validate data checksum here. */ + } + + /* Compressed data can be free now. */ + grub_free (lzopio->block.cdata); + lzopio->block.cdata = NULL; + } + /* Incompressible block of data. */ + else if (lzopio->block.usize == lzopio->block.csize) + { + lzopio->block.udata = lzopio->block.cdata; + lzopio->block.cdata = NULL; + } + else + { + return -1; + } + + return 0; +} + +/* Jump to next block and read its header. */ +static int +jump_block (struct grub_lzopio *lzopio) +{ + /* only jump if block was not decompressed (and read from disk) */ + if (!lzopio->block.udata) + { + grub_off_t off = grub_file_tell (lzopio->file) + lzopio->block.csize; + + if (grub_file_seek (lzopio->file, off) == ((grub_off_t) - 1)) + return -1; + } + + lzopio->saved_off += lzopio->block.usize; + + return read_block_header (lzopio); +} + +static int +calculate_uncompressed_size (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + grub_off_t usize_total = 0; + + if (read_block_header (lzopio) < 0) + return 0; + + /* FIXME: Don't do this for not easily seekable files. */ + while (lzopio->block.usize != 0) + { + usize_total += lzopio->block.usize; + + if (jump_block (lzopio) < 0) + return 0; + } + + file->size = usize_total; + + return 1; +} + +/* XXX Do something with this function, it is insane now:) */ +static int +test_header (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + unsigned char magic[LZOP_MAGIC_SIZE]; + grub_uint16_t lzopver, ver, ver_ext; + grub_uint8_t method, level, name_len; + grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; + unsigned char *name = NULL; + + if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); + return 0; + } + + if (grub_memcmp (magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); + return 0; + } + + /* LZOP version. */ + if (grub_file_read (lzopio->file, &lzopver, sizeof (lzopver)) != + sizeof (lzopver)) + goto CORRUPTED; + + /* LZO lib version. */ + if (grub_file_read (lzopio->file, &ver, sizeof (ver)) != sizeof (ver)) + goto CORRUPTED; + + ver = grub_be_to_cpu16 (ver); + + if (ver >= NEW_LZO_LIB) + { + /* Read version of lib needed to extract data. */ + if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != + sizeof (ver_ext)) + goto CORRUPTED; + + /* Too new version, should upgrade minilzo? */ + if (grub_be_to_cpu16 (ver_ext) > MINILZO_VERSION) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported LZO version"); + return 0; + } + } + + if (grub_file_read (lzopio->file, &method, sizeof (method)) != + sizeof (method)) + goto CORRUPTED; + + if (ver >= NEW_LZO_LIB) + { + if (grub_file_read (lzopio->file, &level, sizeof (level)) != + sizeof (level)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &flags, sizeof (flags)) != sizeof (flags)) + goto CORRUPTED; + + flags = grub_be_to_cpu32 (flags); + + if (flags & F_CRC32_D) + lzopio->ucheck = 1; + else if (flags & F_ADLER32_D) + lzopio->ucheck = 2; + + if (flags & F_CRC32_C) + lzopio->ccheck = 1; + else if (flags & F_ADLER32_C) + lzopio->ccheck = 2; + + if (flags & F_H_FILTER) + { + if (grub_file_read (lzopio->file, &filter, sizeof (filter)) != + sizeof (filter)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &mode, sizeof (mode)) != sizeof (mode)) + goto CORRUPTED; + + if (grub_file_read (lzopio->file, &mtime_lo, sizeof (mtime_lo)) != + sizeof (mtime_lo)) + goto CORRUPTED; + + if (ver >= NEW_LZO_LIB) + { + if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != + sizeof (mtime_hi)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &name_len, sizeof (name_len)) != + sizeof (name_len)) + goto CORRUPTED; + + if (name_len != 0) + { + name = grub_malloc (name_len); + if (!name) + return 0; + + if (grub_file_read (lzopio->file, name, name_len) != name_len) + { + grub_free (name); + goto CORRUPTED; + } + } + + if (grub_file_read (lzopio->file, &checksum, sizeof (checksum)) != + sizeof (checksum)) + { + grub_free (name); + goto CORRUPTED; + } + + grub_free (name); + + /* XXX Validate header checksum here. */ + if (checksum == checksum) + { + lzopio->start_block_off = grub_file_tell (lzopio->file); + + if (calculate_uncompressed_size (file) < 0) + goto CORRUPTED; + + lzopio->saved_off = 0; + + /* Get back to start block. */ + grub_file_seek (lzopio->file, lzopio->start_block_off); + + /* Read first block - grub_lzopio_read() expects valid block. */ + if (read_block_header (lzopio) < 0) + goto CORRUPTED; + + return 1; + } + +CORRUPTED: + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + return 0; +} + +static grub_file_t +grub_lzopio_open (grub_file_t io) +{ + grub_file_t file; + grub_lzopio_t lzopio; + + file = (grub_file_t) grub_zalloc (sizeof (*file)); + if (!file) + return 0; + + lzopio = grub_zalloc (sizeof (*lzopio)); + if (!lzopio) + { + grub_free (file); + return 0; + } + + lzopio->file = io; + + file->device = io->device; + file->offset = 0; + file->data = lzopio; + file->read_hook = 0; + file->fs = &grub_lzopio_fs; + file->size = GRUB_FILE_SIZE_UNKNOWN; + file->not_easily_seekable = 1; + + if (grub_file_tell (lzopio->file) != 0) + grub_file_seek (lzopio->file, 0); + + if (!test_header (file)) + { + grub_errno = GRUB_ERR_NONE; + grub_file_seek (io, 0); + grub_free (lzopio); + grub_free (file); + + return io; + } + + return file; +} + +static grub_ssize_t +grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_lzopio_t lzopio = file->data; + grub_ssize_t ret = 0; + + /* Backward seek before last read block. */ + if (lzopio->saved_off > grub_file_tell (file)) + { + lzopio->saved_off = 0; + grub_file_seek (lzopio->file, lzopio->start_block_off); + + if (read_block_header (lzopio) < 0) + goto CORRUPTED; + } + + /* Forward to first block with requested data. */ + while (lzopio->saved_off + lzopio->block.usize <= grub_file_tell (file)) + { + /* EOF, could be possible files with unknown size. */ + if (lzopio->block.usize == 0) + return 0; + + if (jump_block (lzopio) < 0) + goto CORRUPTED; + } + + while (len != 0 && lzopio->block.usize != 0) + { + grub_off_t off = grub_file_tell (file) - lzopio->saved_off; + long to_copy; + + /* Block not decompressed yet. */ + if (!lzopio->block.udata && uncompress_block (lzopio) < 0) + goto CORRUPTED; + + /* Copy requested data into buffer. */ + to_copy = grub_min (lzopio->block.usize - off, len); + grub_memcpy (buf, lzopio->block.udata + off, to_copy); + + len -= to_copy; + buf += to_copy; + ret += to_copy; + + /* Read to next block if needed. */ + if (len > 0 && read_block_header (lzopio) < 0) + goto CORRUPTED; + } + + return ret; + +CORRUPTED: + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + return -1; +} + +/* Release everything, including the underlying file object. */ +static grub_err_t +grub_lzopio_close (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + + grub_file_close (lzopio->file); + grub_free (lzopio->block.cdata); + grub_free (lzopio->block.udata); + grub_free (lzopio); + + /* Device must not be closed twice. */ + file->device = 0; + return grub_errno; +} + +static struct grub_fs grub_lzopio_fs = { + .name = "lzopio", + .dir = 0, + .open = 0, + .read = grub_lzopio_read, + .close = grub_lzopio_close, + .label = 0, + .next = 0 +}; + +GRUB_MOD_INIT (lzopio) +{ + grub_file_filter_register (GRUB_FILE_FILTER_LZOPIO, grub_lzopio_open); +} + +GRUB_MOD_FINI (lzopio) +{ + grub_file_filter_unregister (GRUB_FILE_FILTER_LZOPIO); +} diff --git a/include/grub/file.h b/include/grub/file.h index 3adb1706f..8fe87e6b4 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -56,6 +56,7 @@ typedef enum grub_file_filter_id { GRUB_FILE_FILTER_GZIO, GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_LZOPIO, GRUB_FILE_FILTER_MAX, GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_XZIO, From 4334690fbf512f5df2de965e8f5a89695734184e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 02:05:08 +0200 Subject: [PATCH 040/315] More work on LZO for btrfs support. Some fixes and code refactoring. --- ChangeLog.lzo | 11 +++ grub-core/fs/btrfs.c | 176 +++++++++++++++++++++---------------------- 2 files changed, 96 insertions(+), 91 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 782c6b60d..2ff940e21 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,14 @@ +2011-08-20 Szymon Janc + + More work on LZO for btrfs support. Some fixes and code refactoring. + + * grub-core/fs/btrfs.c (grub_btrfs_superblock): Removed sectorsize, + nodesize, leafsize, stripsize and dummy5 fields. + (grub_btrfs_lzo_decompress): New function. + (grub_btrfs_extent_read): Use grub_btrfs_lzo_decompress for LZO blocks + decompression. + (GRUB_BTRFS_LZO_BLOCK_SIZE): New define. + 2011-08-17 Szymon Janc Add initial support for lzop files decompression. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 1d24da3e3..7af735630 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -31,6 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BTRFS_SIGNATURE "_BHRfS_M" +#define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; typedef grub_uint16_t grub_btrfs_uuid_t[8]; @@ -52,15 +53,10 @@ struct grub_btrfs_superblock grub_uint64_t chunk_tree; grub_uint8_t dummy2[0x20]; grub_uint64_t root_dir_objectid; - grub_uint8_t dummy3[0x8]; - grub_uint32_t sectorsize; - grub_uint32_t nodesize; - grub_uint32_t leafsize; - grub_uint32_t stripsize; - grub_uint8_t dummy4[0x29]; + grub_uint8_t dummy3[0x41]; struct grub_btrfs_device this_device; char label[0x100]; - grub_uint8_t dummy5[0x100]; + grub_uint8_t dummy4[0x100]; grub_uint8_t bootstrap_mapping[0x800]; } __attribute__ ((packed)); @@ -884,6 +880,77 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode)); } +static int +grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, + char *obuf, grub_size_t osize) +{ + grub_uint32_t total_size, cblock_size; + unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; + + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + if (isize < total_size) + return -1; + + while (osize != 0) + { + lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; + + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_SIZE) + return -1; + + /* Jump forward to first block with requested data. */ + if (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; + ibuf += cblock_size; + continue; + } + + /* First block partially filled with requested data. */ + if (off > 0) + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, + NULL) != LZO_E_OK) + return -1; + + grub_memcpy(obuf, buf + off, usize - off); + + osize -= usize - off; + obuf += usize - off; + ibuf += cblock_size; + off = 0; + continue; + } + + /* 'Main' case, decompress whole block directly to output buffer. */ + if (osize >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, + (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) + return -1; + + osize -= usize; + obuf += usize; + ibuf += cblock_size; + } + else /* Last possible block partially filled with requested data. */ + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, + NULL) != LZO_E_OK) + return -1; + + grub_memcpy(obuf, buf, osize); + break; + } + } + return 0; +} + static grub_ssize_t grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_uint64_t ino, grub_uint64_t tree, @@ -990,39 +1057,11 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) { - grub_uint32_t total_size, chunk_size; - unsigned char *obuf; - unsigned char *ibuf = (unsigned char *) data->extent->inl; - lzo_uint ocnt = extoff + csize; - int ret; - - obuf = grub_malloc (extoff + csize); - if (!obuf) + if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) < 0) return -1; - - total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (total_size); - - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); - - /* Can we have multiple chunks in inline extent? */ - if (chunk_size + (sizeof (grub_uint32_t) * 2) != total_size) - { - grub_free (obuf); - return -1; - } - - ret = lzo1x_decompress_safe (ibuf, chunk_size, obuf, &ocnt, NULL); - - if (ret != LZO_E_OK) - { - grub_free (obuf); - return -1; - } - - grub_memcpy (buf, obuf + extoff, ocnt - extoff); - grub_free (obuf); } else grub_memcpy (buf, data->extent->inl + extoff, csize); @@ -1068,62 +1107,17 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) { - grub_uint32_t total_size, chunk_size, usize = 0; - grub_size_t off = extoff; - unsigned char *chunk, *ibuf = tmp; - char *obuf = buf; - /* XXX Is this correct size from sblock? */ - grub_uint32_t udata_size = grub_le_to_cpu32 (data->sblock.sectorsize); + int ret ; - chunk = grub_malloc (udata_size); - if (!chunk) - { - grub_free (tmp); - return -1; - } + ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); - /* XXX Use this for some sanity checks while decompressing. */ - total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (total_size); + grub_free(tmp); - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); + if (ret < 0) + return -1; - /* Jump to first chunk with requested data. */ - while (off >= udata_size) - { - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); - ibuf += chunk_size; - off -= udata_size; - } - - while (usize < csize) - { - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - lzo_uint csize2 = udata_size; - int diff; - - ibuf += sizeof (chunk_size); - - if (lzo1x_decompress_safe (ibuf, chunk_size, chunk, &csize2, NULL) != LZO_E_OK) - { - grub_free (tmp); - grub_free (chunk); - return -1; - } - - diff = grub_min (csize2 - off, csize - usize); - - grub_memcpy (obuf, chunk + off, diff); - obuf += diff; - ibuf += chunk_size; - usize += diff; - off = 0; - } - - grub_free (tmp); - grub_free (chunk); break; } } From 9a8d32a24fe7d0a1865be8ae83308cc001d1d091 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 18:24:54 +0200 Subject: [PATCH 041/315] Add support for adler32 checksuming. * grub-core/lib/adler32.c: New file. * Makefile.util.def (library): Add grub-core/lib/adler32.c to common. * util/import_gcry.py (cryptolist): Add adler32. --- ChangeLog.lzo | 8 ++ Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 ++ grub-core/lib/adler32.c | 152 ++++++++++++++++++++++++++++++++++++ util/import_gcry.py | 2 + 5 files changed, 168 insertions(+) create mode 100644 grub-core/lib/adler32.c diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 2ff940e21..d24d913d8 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,11 @@ +2011-08-20 Szymon Janc + + Add support for adler32 checksuming. + + * grub-core/lib/adler32.c: New file. + * Makefile.util.def (library): Add grub-core/lib/adler32.c to common. + * util/import_gcry.py (cryptolist): Add adler32. + 2011-08-20 Szymon Janc More work on LZO for btrfs support. Some fixes and code refactoring. diff --git a/Makefile.util.def b/Makefile.util.def index 3628e48f6..365f718a1 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -91,6 +91,7 @@ library = { common = grub-core/lib/LzFind.c; common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/crc.c; + common = grub-core/lib/adler32.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fc017b780..77dc7ed4b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1687,3 +1687,8 @@ module = { common = commands/cacheinfo.c; condition = COND_ENABLE_CACHE_STATS; }; + +module = { + name = adler32; + common = lib/adler32.c; +}; diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c new file mode 100644 index 000000000..cc40735cb --- /dev/null +++ b/grub-core/lib/adler32.c @@ -0,0 +1,152 @@ +/* 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 . + */ + +#include +#include +#include + +/* 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; + grub_uint8_t buf[4]; +} +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 ctx->buf; +} + +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); +} diff --git a/util/import_gcry.py b/util/import_gcry.py index 727492f10..ee75b1b8e 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -81,6 +81,8 @@ cryptolist.write ("AES-128: gcry_rijndael\n"); cryptolist.write ("AES-192: gcry_rijndael\n"); cryptolist.write ("AES-256: gcry_rijndael\n"); +cryptolist.write ("ADLER32: adler32\n"); + for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file) outfile = os.path.join (cipher_dir_out, cipher_file) From 6401c37058fd2ea0ddf187d6a8c2563471dc0252 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 21 Aug 2011 14:49:07 +0200 Subject: [PATCH 042/315] Return correct adler32 value in read() call. --- grub-core/lib/adler32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c index cc40735cb..6fb0b00f8 100644 --- a/grub-core/lib/adler32.c +++ b/grub-core/lib/adler32.c @@ -102,7 +102,6 @@ update_adler32 (grub_uint32_t adler, const grub_uint8_t *buf, grub_size_t len) typedef struct { grub_uint32_t adler; - grub_uint8_t buf[4]; } adler32_context; @@ -126,7 +125,7 @@ static grub_uint8_t * adler32_read (void *context) { adler32_context *ctx = (adler32_context *) context; - return ctx->buf; + return (grub_uint8_t *) &ctx->adler; } static void From 90b0a05579001a4474b69f65c98501bb8078a8c3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 21 Aug 2011 18:48:19 +0200 Subject: [PATCH 043/315] Various bug fixes and improvements in lzopio. Should properly handle more files now. Also added support for lzop checksums verification. --- grub-core/io/lzopio.c | 174 +++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 61 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 4ccc41a16..f80d4beb9 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -22,17 +22,15 @@ #include #include #include - +#include #include "minilzo.h" GRUB_MOD_LICENSE ("GPLv3+"); #define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" #define LZOP_MAGIC_SIZE 9 -#define CHECK_SIZE 4 -#define NEW_LZO_LIB 0x0940 -#define MIN_HEADER_SIZE 0 -#define MAX_HEADER_SIZE 0 +#define LZOP_CHECK_SIZE 4 +#define LZOP_NEW_LIB 0x0940 /* Header flags - copied from conf.h of LZOP source code. */ #define F_ADLER32_D 0x00000001L @@ -64,8 +62,10 @@ struct block_header struct grub_lzopio { grub_file_t file; - int ucheck; /* XXX Use gcry to validate checks. */ - int ccheck; + int has_ccheck; + int has_ucheck; + const gcry_md_spec_t *ucheck_fun; + const gcry_md_spec_t *ccheck_fun; grub_off_t saved_off; /* Rounded down to block boundary. */ grub_off_t start_block_off; struct block_header block; @@ -74,15 +74,16 @@ struct grub_lzopio typedef struct grub_lzopio *grub_lzopio_t; static struct grub_fs grub_lzopio_fs; -/* Some helper functions. Memory allocated by those function is free either - * on next read_block_header() or on close() so no risk of leaks. This makes - * those function simpler. */ +/* Some helper functions. On errors memory allocated by those function is free + * either on close() so no risk of leaks. This makes functions simpler. */ /* Read block header from file, after successful exit file points to * beginning of block data. */ static int read_block_header (struct grub_lzopio *lzopio) { + lzopio->saved_off += lzopio->block.usize; + /* Free cached block data if any. */ grub_free (lzopio->block.udata); grub_free (lzopio->block.cdata); @@ -113,26 +114,40 @@ read_block_header (struct grub_lzopio *lzopio) lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize); - /* XXX Handle incompressible data case here rather than in uncompress_block. - * This will allow to handle switch of ccheck/ucheck easier and also - * make uncompress_block() a bit simpler. */ + /* Corrupted. */ + if (lzopio->block.csize > lzopio->block.usize) + return -1; - /* Read data checks. */ - if (lzopio->ucheck) + /* Read checksum of uncompressed data. */ + if (lzopio->has_ucheck) { if (grub_file_read (lzopio->file, &lzopio->block.ucheck, sizeof (lzopio->block.ucheck)) != sizeof (lzopio->block.ucheck)) return -1; + + lzopio->block.ucheck = grub_be_to_cpu32 (lzopio->block.ucheck); } - if (lzopio->ccheck) + /* Read checksum of compressed data. */ + if (lzopio->has_ccheck) { - if (grub_file_read (lzopio->file, &lzopio->block.ccheck, - sizeof (lzopio->block.ccheck)) != - sizeof (lzopio->block.ccheck)) - return -1; + /* Incompressible data block. */ + if (lzopio->block.csize == lzopio->block.usize) + { + lzopio->block.ccheck = lzopio->block.ucheck; + } + else + { + if (grub_file_read (lzopio->file, &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != + sizeof (lzopio->block.ccheck)) + return -1; + + lzopio->block.ccheck = grub_be_to_cpu32 (lzopio->block.ccheck); + } } + return 0; } @@ -149,9 +164,19 @@ read_block_data (struct grub_lzopio *lzopio) != (grub_ssize_t) lzopio->block.csize) return -1; - if (lzopio->ccheck) + if (lzopio->ccheck_fun) { - /* XXX Validate data checksum here. */ + grub_uint8_t context[lzopio->ccheck_fun->contextsize]; + + lzopio->ccheck_fun->init (context); + lzopio->ccheck_fun->write (context, lzopio->block.cdata, + lzopio->block.csize); + lzopio->ccheck_fun->final (context); + + if (grub_memcmp + (lzopio->ccheck_fun->read (context), &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != 0) + return -1; } return 0; @@ -159,7 +184,7 @@ read_block_data (struct grub_lzopio *lzopio) /* Read block data, uncompressed and also store it in memory. */ /* XXX Investigate possibility of in-place decompression to reduce memory - * footprint. */ + * footprint. Or try to uncompress directly to buf if possible. */ static int uncompress_block (struct grub_lzopio *lzopio) { @@ -168,35 +193,41 @@ uncompress_block (struct grub_lzopio *lzopio) if (read_block_data (lzopio) < 0) return -1; - if (lzopio->block.usize > lzopio->block.csize) - { - lzopio->block.udata = grub_malloc (lzopio->block.usize); - if (!lzopio->block.udata) - return -1; - - if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, - lzopio->block.udata, &usize, - NULL) != LZO_E_OK) - return -1; - - if (lzopio->ucheck) - { - /* XXX Validate data checksum here. */ - } - - /* Compressed data can be free now. */ - grub_free (lzopio->block.cdata); - lzopio->block.cdata = NULL; - } - /* Incompressible block of data. */ - else if (lzopio->block.usize == lzopio->block.csize) + /* Incompressible data. */ + if (lzopio->block.csize == lzopio->block.usize) { lzopio->block.udata = lzopio->block.cdata; lzopio->block.cdata = NULL; } else { - return -1; + lzopio->block.udata = grub_malloc (lzopio->block.usize); + if (!lzopio->block.udata) + return -1; + + if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, + lzopio->block.udata, &usize, NULL) + != LZO_E_OK) + return -1; + + if (lzopio->ucheck_fun) + { + grub_uint8_t context[lzopio->ucheck_fun->contextsize]; + + lzopio->ucheck_fun->init (context); + lzopio->ucheck_fun->write (context, lzopio->block.udata, + lzopio->block.usize); + lzopio->ucheck_fun->final (context); + + if (grub_memcmp + (lzopio->ucheck_fun->read (context), &lzopio->block.ucheck, + sizeof (lzopio->block.ucheck)) != 0) + return -1; + } + + /* Compressed data can be free now. */ + grub_free (lzopio->block.cdata); + lzopio->block.cdata = NULL; } return 0; @@ -215,8 +246,6 @@ jump_block (struct grub_lzopio *lzopio) return -1; } - lzopio->saved_off += lzopio->block.usize; - return read_block_header (lzopio); } @@ -243,7 +272,7 @@ calculate_uncompressed_size (grub_file_t file) return 1; } -/* XXX Do something with this function, it is insane now:) */ +/* XXX Do something with this function... */ static int test_header (grub_file_t file) { @@ -253,6 +282,7 @@ test_header (grub_file_t file) grub_uint8_t method, level, name_len; grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; unsigned char *name = NULL; + const gcry_md_spec_t *hcheck; if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) { @@ -277,7 +307,7 @@ test_header (grub_file_t file) ver = grub_be_to_cpu16 (ver); - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { /* Read version of lib needed to extract data. */ if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != @@ -297,7 +327,7 @@ test_header (grub_file_t file) sizeof (method)) goto CORRUPTED; - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { if (grub_file_read (lzopio->file, &level, sizeof (level)) != sizeof (level)) @@ -310,14 +340,33 @@ test_header (grub_file_t file) flags = grub_be_to_cpu32 (flags); if (flags & F_CRC32_D) - lzopio->ucheck = 1; + { + lzopio->has_ucheck = 1; + lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("crc32"); + } else if (flags & F_ADLER32_D) - lzopio->ucheck = 2; + { + lzopio->has_ucheck = 1; + lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("adler32"); + } if (flags & F_CRC32_C) - lzopio->ccheck = 1; + { + lzopio->has_ccheck = 1; + lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("crc32"); + } else if (flags & F_ADLER32_C) - lzopio->ccheck = 2; + { + lzopio->has_ccheck = 1; + lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("adler32"); + } + + if (flags & F_H_CRC32) + hcheck = grub_crypto_lookup_md_by_name ("crc32"); + else + hcheck = grub_crypto_lookup_md_by_name ("adler32"); + + hcheck++; if (flags & F_H_FILTER) { @@ -333,7 +382,7 @@ test_header (grub_file_t file) sizeof (mtime_lo)) goto CORRUPTED; - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != sizeof (mtime_hi)) @@ -374,8 +423,6 @@ test_header (grub_file_t file) if (calculate_uncompressed_size (file) < 0) goto CORRUPTED; - lzopio->saved_off = 0; - /* Get back to start block. */ grub_file_seek (lzopio->file, lzopio->start_block_off); @@ -383,6 +430,7 @@ test_header (grub_file_t file) if (read_block_header (lzopio) < 0) goto CORRUPTED; + lzopio->saved_off = 0; return 1; } @@ -439,15 +487,17 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) { grub_lzopio_t lzopio = file->data; grub_ssize_t ret = 0; + grub_off_t off; /* Backward seek before last read block. */ if (lzopio->saved_off > grub_file_tell (file)) { - lzopio->saved_off = 0; grub_file_seek (lzopio->file, lzopio->start_block_off); if (read_block_header (lzopio) < 0) goto CORRUPTED; + + lzopio->saved_off = 0; } /* Forward to first block with requested data. */ @@ -461,9 +511,10 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) goto CORRUPTED; } + off = grub_file_tell (file) - lzopio->saved_off; + while (len != 0 && lzopio->block.usize != 0) { - grub_off_t off = grub_file_tell (file) - lzopio->saved_off; long to_copy; /* Block not decompressed yet. */ @@ -477,8 +528,9 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) len -= to_copy; buf += to_copy; ret += to_copy; + off = 0; - /* Read to next block if needed. */ + /* Read next block if needed. */ if (len > 0 && read_block_header (lzopio) < 0) goto CORRUPTED; } From 1f0e4eed6bdd61b8653625bfb5646bb3d70365be Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 22 Aug 2011 09:18:22 +0200 Subject: [PATCH 044/315] * include/grub/file.h (grub_file_filter_id): Set GRUB_FILE_FILTER_LZOPIO as GRUB_FILE_FILTER_COMPRESSION_LAST. --- ChangeLog.lzo | 5 +++++ include/grub/file.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index d24d913d8..e3d08c6da 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,8 @@ +2011-08-22 Szymon Janc + + * include/grub/file.h (grub_file_filter_id): Set + GRUB_FILE_FILTER_LZOPIO as GRUB_FILE_FILTER_COMPRESSION_LAST. + 2011-08-20 Szymon Janc Add support for adler32 checksuming. diff --git a/include/grub/file.h b/include/grub/file.h index 8fe87e6b4..e08ac2e26 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -59,7 +59,7 @@ typedef enum grub_file_filter_id GRUB_FILE_FILTER_LZOPIO, GRUB_FILE_FILTER_MAX, GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, } grub_file_filter_id_t; typedef grub_file_t (*grub_file_filter_t) (grub_file_t in); From 00b98c9b2ef86d4cc4254dd163798388fc1f4d52 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 23 Aug 2011 19:49:01 +0200 Subject: [PATCH 045/315] * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Random fixes and some cleanup. --- grub-core/fs/btrfs.c | 120 ++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7af735630..ae1ce1c7d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -31,7 +31,17 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BTRFS_SIGNATURE "_BHRfS_M" + +/* From http://www.oberhumer.com/opensource/lzo/lzofaq.php + * LZO will expand incompressible data by a little amount. I still haven't + * computed the exact values, but I suggest using these formulas for + * a worst-case expansion calculation: + * + * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + * */ #define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 +#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \ + (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3) typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; typedef grub_uint16_t grub_btrfs_uuid_t[8]; @@ -880,11 +890,11 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode)); } -static int +static grub_ssize_t grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) { - grub_uint32_t total_size, cblock_size; + grub_uint32_t total_size, cblock_size, uncompressed = 0; unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -893,62 +903,54 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, if (isize < total_size) return -1; - while (osize != 0) + /* Jump forward to first block with requested data. */ + while (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; + ibuf += cblock_size; + } + + while (osize > 0) { lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); - if (cblock_size > GRUB_BTRFS_LZO_BLOCK_SIZE) - return -1; - - /* Jump forward to first block with requested data. */ - if (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + /* Block partially filled with requested data. */ + if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { - off -= GRUB_BTRFS_LZO_BLOCK_SIZE; - ibuf += cblock_size; - continue; - } + grub_size_t to_copy = grub_min(osize, GRUB_BTRFS_LZO_BLOCK_SIZE - off); - /* First block partially filled with requested data. */ - if (off > 0) - { if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, NULL) != LZO_E_OK) return -1; - grub_memcpy(obuf, buf + off, usize - off); + grub_memcpy(obuf, buf + off, to_copy); - osize -= usize - off; - obuf += usize - off; + osize -= to_copy; + uncompressed += to_copy; + obuf += to_copy; ibuf += cblock_size; off = 0; continue; } /* 'Main' case, decompress whole block directly to output buffer. */ - if (osize >= GRUB_BTRFS_LZO_BLOCK_SIZE) - { - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, - (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) - return -1; + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, + &usize, NULL) != LZO_E_OK) + return -1; - osize -= usize; - obuf += usize; - ibuf += cblock_size; - } - else /* Last possible block partially filled with requested data. */ - { - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, - NULL) != LZO_E_OK) - return -1; - - grub_memcpy(obuf, buf, osize); - break; - } + osize -= usize; + uncompressed += usize; + obuf += usize; + ibuf += cblock_size; } - return 0; + + return uncompressed; } static grub_ssize_t @@ -1060,7 +1062,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - ((grub_uint8_t *) data->extent->inl - (grub_uint8_t *) data->extent), - extoff, buf, csize) < 0) + extoff, buf, csize) + != (grub_ssize_t) csize) return -1; } else @@ -1075,8 +1078,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) { - void *tmp; + char *tmp; grub_uint64_t zsize; + grub_ssize_t ret; + zsize = grub_le_to_cpu64 (data->extent->compressed_size); tmp = grub_malloc (zsize); if (!tmp) @@ -1091,36 +1096,23 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) - { - grub_ssize_t ret; - - ret = grub_zlib_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), - buf, csize); - - grub_free (tmp); - - if (ret != (grub_ssize_t) csize) - return -1; - - break; - } - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) - { - int ret ; - - ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + ret = grub_zlib_decompress (tmp, zsize, extoff + grub_le_to_cpu64 (data->extent->offset), buf, csize); + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + else + ret = -1; - grub_free(tmp); + grub_free(tmp); - if (ret < 0) - return -1; + if (ret != (grub_ssize_t) csize) + return -1; - break; - } - } + break; + } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) From ec543969bf07fbe60423ece81b29cd315116388b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 23 Aug 2011 19:53:49 +0200 Subject: [PATCH 046/315] * Makefile.util.def (libgrubmods.a): Add grub-core/io/lzopio.c to common. --- ChangeLog.lzo | 5 +++++ Makefile.util.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index e3d08c6da..ef6145061 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,8 @@ +2011-08-23 Szymon Janc + + * Makefile.util.def (libgrubmods.a): Add grub-core/io/lzopio.c to + common. + 2011-08-22 Szymon Janc * include/grub/file.h (grub_file_filter_id): Set diff --git a/Makefile.util.def b/Makefile.util.def index 365f718a1..1fe4f2464 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -109,6 +109,7 @@ library = { common = grub-core/script/script.c; common = grub-core/script/argv.c; common = grub-core/io/gzio.c; + common = grub-core/io/lzopio.c; common = grub-core/kern/ia64/dl_helper.c; common = grub-core/lib/minilzo/minilzo.c; }; From 579c12fbb4b757fc26cb6fcbe265250f734eaf68 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 24 Aug 2011 11:24:10 +0200 Subject: [PATCH 047/315] * grub-core/fs/btrfs.c: Some minor cleanups. --- grub-core/fs/btrfs.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ae1ce1c7d..534ce15de 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -894,7 +894,7 @@ static grub_ssize_t grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) { - grub_uint32_t total_size, cblock_size, uncompressed = 0; + grub_uint32_t total_size, cblock_size, ret = 0; unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -909,6 +909,9 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; ibuf += cblock_size; } @@ -920,6 +923,9 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + /* Block partially filled with requested data. */ if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { @@ -929,28 +935,29 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, NULL) != LZO_E_OK) return -1; + to_copy = grub_min(to_copy, usize); grub_memcpy(obuf, buf + off, to_copy); osize -= to_copy; - uncompressed += to_copy; + ret += to_copy; obuf += to_copy; ibuf += cblock_size; off = 0; continue; } - /* 'Main' case, decompress whole block directly to output buffer. */ + /* Decompress whole block directly to output buffer. */ if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) return -1; osize -= usize; - uncompressed += usize; + ret += usize; obuf += usize; ibuf += cblock_size; } - return uncompressed; + return ret; } static grub_ssize_t From 9c4f9ca010ddf432c7c83cdabaf36c7a4b956cd6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 6 Sep 2011 21:21:13 +0200 Subject: [PATCH 048/315] * grub-core/io/lzopio.c (test_header): Some cleanups. --- grub-core/io/lzopio.c | 177 +++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 96 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index f80d4beb9..e303b29a3 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -272,72 +272,60 @@ calculate_uncompressed_size (grub_file_t file) return 1; } -/* XXX Do something with this function... */ +struct lzop_header +{ + grub_uint8_t magic[LZOP_MAGIC_SIZE]; + grub_uint16_t lzop_version; + grub_uint16_t lib_version; + grub_uint16_t lib_version_ext; + grub_uint8_t method; + grub_uint8_t level; + grub_uint32_t flags; + /* grub_uint32_t filter; */ /* No filters support. Rarely used anyway. */ + grub_uint32_t mode; + grub_uint32_t mtime_lo; + grub_uint32_t mtime_hi; + grub_uint8_t name_len; +} __attribute__ ((packed)); + static int test_header (grub_file_t file) { grub_lzopio_t lzopio = file->data; - unsigned char magic[LZOP_MAGIC_SIZE]; - grub_uint16_t lzopver, ver, ver_ext; - grub_uint8_t method, level, name_len; - grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; - unsigned char *name = NULL; + struct lzop_header header; + grub_uint32_t flags, checksum; const gcry_md_spec_t *hcheck; + grub_uint8_t *context = NULL; + grub_uint8_t *name = NULL; - if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) + if (grub_file_read (lzopio->file, &header, sizeof (header)) != sizeof (header)) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); return 0; } - if (grub_memcmp (magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) + if (grub_memcmp (header.magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); return 0; } - /* LZOP version. */ - if (grub_file_read (lzopio->file, &lzopver, sizeof (lzopver)) != - sizeof (lzopver)) - goto CORRUPTED; - - /* LZO lib version. */ - if (grub_file_read (lzopio->file, &ver, sizeof (ver)) != sizeof (ver)) - goto CORRUPTED; - - ver = grub_be_to_cpu16 (ver); - - if (ver >= LZOP_NEW_LIB) + if (grub_be_to_cpu16(header.lib_version) < LZOP_NEW_LIB) { - /* Read version of lib needed to extract data. */ - if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != - sizeof (ver_ext)) - goto CORRUPTED; - - /* Too new version, should upgrade minilzo? */ - if (grub_be_to_cpu16 (ver_ext) > MINILZO_VERSION) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "unsupported LZO version"); - return 0; - } + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported (too old) LZOP version"); + return 0; } - if (grub_file_read (lzopio->file, &method, sizeof (method)) != - sizeof (method)) - goto CORRUPTED; - - if (ver >= LZOP_NEW_LIB) + /* Too new version, should upgrade minilzo? */ + if (grub_be_to_cpu16 (header.lib_version_ext) > MINILZO_VERSION) { - if (grub_file_read (lzopio->file, &level, sizeof (level)) != - sizeof (level)) - goto CORRUPTED; + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported (too new) LZO version"); + return 0; } - if (grub_file_read (lzopio->file, &flags, sizeof (flags)) != sizeof (flags)) - goto CORRUPTED; - - flags = grub_be_to_cpu32 (flags); + flags = grub_be_to_cpu32 (header.flags); if (flags & F_CRC32_D) { @@ -366,76 +354,73 @@ test_header (grub_file_t file) else hcheck = grub_crypto_lookup_md_by_name ("adler32"); - hcheck++; + if (hcheck) { + context = grub_malloc(hcheck->contextsize); + if (! context) + return 0; - if (flags & F_H_FILTER) + hcheck->init(context); + + /* MAGIC is not included in check calculation. */ + hcheck->write(context, &header.lzop_version, sizeof(header)- LZOP_MAGIC_SIZE); + } + + if (header.name_len != 0) { - if (grub_file_read (lzopio->file, &filter, sizeof (filter)) != - sizeof (filter)) - goto CORRUPTED; - } - - if (grub_file_read (lzopio->file, &mode, sizeof (mode)) != sizeof (mode)) - goto CORRUPTED; - - if (grub_file_read (lzopio->file, &mtime_lo, sizeof (mtime_lo)) != - sizeof (mtime_lo)) - goto CORRUPTED; - - if (ver >= LZOP_NEW_LIB) - { - if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != - sizeof (mtime_hi)) - goto CORRUPTED; - } - - if (grub_file_read (lzopio->file, &name_len, sizeof (name_len)) != - sizeof (name_len)) - goto CORRUPTED; - - if (name_len != 0) - { - name = grub_malloc (name_len); - if (!name) - return 0; - - if (grub_file_read (lzopio->file, name, name_len) != name_len) + name = grub_malloc (header.name_len); + if (! name) { - grub_free (name); + grub_free (context); + return 0; + } + + if (grub_file_read (lzopio->file, name, header.name_len) != + header.name_len) + { + grub_free(name); goto CORRUPTED; } + + if (hcheck) + hcheck->write(context, name, header.name_len); + + grub_free(name); } + if (hcheck) + hcheck->final(context); + if (grub_file_read (lzopio->file, &checksum, sizeof (checksum)) != sizeof (checksum)) - { - grub_free (name); + goto CORRUPTED; + + if (hcheck) + { + checksum = grub_cpu_to_be32(checksum); + if (memcmp(&checksum, hcheck->read(context), sizeof(checksum)) != 0) goto CORRUPTED; - } + } - grub_free (name); + lzopio->start_block_off = grub_file_tell (lzopio->file); - /* XXX Validate header checksum here. */ - if (checksum == checksum) - { - lzopio->start_block_off = grub_file_tell (lzopio->file); + if (calculate_uncompressed_size (file) < 0) + goto CORRUPTED; - if (calculate_uncompressed_size (file) < 0) - goto CORRUPTED; + /* Get back to start block. */ + grub_file_seek (lzopio->file, lzopio->start_block_off); - /* Get back to start block. */ - grub_file_seek (lzopio->file, lzopio->start_block_off); + /* Read first block - grub_lzopio_read() expects valid block. */ + if (read_block_header (lzopio) < 0) + goto CORRUPTED; - /* Read first block - grub_lzopio_read() expects valid block. */ - if (read_block_header (lzopio) < 0) - goto CORRUPTED; - - lzopio->saved_off = 0; - return 1; - } + lzopio->saved_off = 0; + return 1; CORRUPTED: grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + + grub_free(name); + return 0; } From 139d67a82fb1738e642424e2d425916d97c8e098 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 21:50:32 +0200 Subject: [PATCH 049/315] * grub-core/fs/btrfs.c: Fix code style regressions. --- grub-core/fs/btrfs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 534ce15de..5b8dca559 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -330,8 +330,8 @@ next (struct grub_btrfs_data *data, for (; desc->depth > 0; desc->depth--) { desc->data[desc->depth - 1].iter++; - if (desc->data[desc->depth - 1].iter < - desc->data[desc->depth - 1].maxiter) + if (desc->data[desc->depth - 1].iter + < desc->data[desc->depth - 1].maxiter) break; } if (desc->depth == 0) @@ -376,7 +376,7 @@ lower_bound (struct grub_btrfs_data *data, const struct grub_btrfs_key *key_in, struct grub_btrfs_key *key_out, grub_disk_addr_t root, - grub_disk_addr_t * outaddr, grub_size_t * outsize, + grub_disk_addr_t *outaddr, grub_size_t *outsize, struct grub_btrfs_leaf_descriptor *desc) { grub_disk_addr_t addr = root; @@ -626,8 +626,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_le_to_cpu64 (key->offset), grub_le_to_cpu64 (chunk->size)); if (grub_le_to_cpu64 (key->offset) <= addr - && addr < - grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size)) + && addr < grub_le_to_cpu64 (key->offset) + + grub_le_to_cpu64 (chunk->size)) goto chunk_found; ptr += sizeof (*key) + sizeof (*chunk) + sizeof (struct grub_btrfs_chunk_stripe) @@ -1007,8 +1007,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) &data->extent + elemsize >= - (char *) &data->extent->filled + sizeof (data->extent->filled)) + && (char *) &data->extent + elemsize + >= (char *) &data->extent->filled + sizeof (data->extent->filled)) data->extend = data->extstart + grub_le_to_cpu64 (data->extent->filled); @@ -1113,7 +1113,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, else ret = -1; - grub_free(tmp); + grub_free (tmp); if (ret != (grub_ssize_t) csize) return -1; @@ -1142,7 +1142,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, static grub_err_t find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, - grub_uint64_t * tree, grub_uint8_t * type) + grub_uint64_t *tree, grub_uint8_t *type) { const char *slash = path; grub_err_t err; @@ -1391,7 +1391,7 @@ find_path (struct grub_btrfs_data *data, static grub_err_t grub_btrfs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, - const struct grub_dirhook_info * info)) + const struct grub_dirhook_info *info)) { struct grub_btrfs_data *data = grub_btrfs_mount (device); struct grub_btrfs_key key_in, key_out; From c5ed9266fc216a2c62781b87d6a4ff97315a70f0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 22:06:10 +0200 Subject: [PATCH 050/315] * grub-core/io/lzopio.c: Improve crypt context alignment. --- grub-core/io/lzopio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index e303b29a3..d804c31b0 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -166,7 +166,7 @@ read_block_data (struct grub_lzopio *lzopio) if (lzopio->ccheck_fun) { - grub_uint8_t context[lzopio->ccheck_fun->contextsize]; + grub_uint64_t context[(lzopio->ccheck_fun->contextsize + 7) / 8]; lzopio->ccheck_fun->init (context); lzopio->ccheck_fun->write (context, lzopio->block.cdata, @@ -212,7 +212,7 @@ uncompress_block (struct grub_lzopio *lzopio) if (lzopio->ucheck_fun) { - grub_uint8_t context[lzopio->ucheck_fun->contextsize]; + grub_uint64_t context[(lzopio->ccheck_fun->contextsize + 7) / 8]; lzopio->ucheck_fun->init (context); lzopio->ucheck_fun->write (context, lzopio->block.udata, From 0e2b7e39f2e2d9089efb307d9e58aedf3e5b1c57 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 22:25:06 +0200 Subject: [PATCH 051/315] * grub-core/fs/btrfs.c: Include instead of "minilzo.h". * grub-core/io/lzopio.c: Likewise. --- grub-core/fs/btrfs.c | 2 +- grub-core/io/lzopio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 5b8dca559..93642f789 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -26,7 +26,7 @@ #include #include #include -#include "minilzo.h" +#include GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index d804c31b0..e2bbf79b7 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -23,7 +23,7 @@ #include #include #include -#include "minilzo.h" +#include GRUB_MOD_LICENSE ("GPLv3+"); From b871e8ebcca01098727b1bc324e490b8de5a5a1b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 23:01:14 +0200 Subject: [PATCH 052/315] * grub-core/Makefile.core.def (btrfs): Remove minilzo.c from common. --- grub-core/Makefile.core.def | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 77dc7ed4b..b58a75f67 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -980,7 +980,6 @@ module = { name = btrfs; common = fs/btrfs.c; common = lib/crc.c; - common = lib/minilzo/minilzo.c; cflags = '$(CFLAGS_POSIX) -Wno-undef'; cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; From bc4d3f4809353539891a04bc218ff7ef37cb2536 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Oct 2011 21:10:21 +0200 Subject: [PATCH 053/315] * grub-core/io/lzopio.c (calculate_uncompressed_size): Fix return code. --- grub-core/io/lzopio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index e2bbf79b7..02a70f4d8 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -256,7 +256,7 @@ calculate_uncompressed_size (grub_file_t file) grub_off_t usize_total = 0; if (read_block_header (lzopio) < 0) - return 0; + return -1; /* FIXME: Don't do this for not easily seekable files. */ while (lzopio->block.usize != 0) @@ -264,12 +264,12 @@ calculate_uncompressed_size (grub_file_t file) usize_total += lzopio->block.usize; if (jump_block (lzopio) < 0) - return 0; + return -1; } file->size = usize_total; - return 1; + return 0; } struct lzop_header From a98f4a0808308815c5580d3ac23b2442d02ced33 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 9 Oct 2011 21:13:00 +0200 Subject: [PATCH 054/315] 2011-10-09 Robert Millan LVM support for FreeBSD and GNU/kFreeBSD. * util/lvm.c (grub_util_lvm_isvolume): Enable on FreeBSD and GNU/kFreeBSD. (LVM_DEV_MAPPER_STRING): Move from here ... * include/grub/util/lvm.h (LVM_DEV_MAPPER_STRING): ... to here. * util/getroot.c: Include `'. (grub_util_get_dev_abstraction): Enable grub_util_biosdisk_is_present() on FreeBSD and GNU/kFreeBSD. Check for LVM abstraction on FreeBSD and GNU/kFreeBSD. (grub_util_get_grub_dev): Replace "/dev/mapper/" with `LVM_DEV_MAPPER_STRING'. Enable LVM and mdRAID only on platforms that support it. * util/grub-setup.c (main): Check for LVM also on FreeBSD and GNU/kFreeBSD. * util/grub.d/10_kfreebsd.in: Load `geom_linux_lvm' kernel module when LVM abstraction is required for ${GRUB_DEVICE}. --- ChangeLog | 20 ++++++++++++++++++++ include/grub/util/lvm.h | 9 ++++++++- util/getroot.c | 24 ++++++++++++++++-------- util/grub-setup.c | 6 ++++-- util/grub.d/10_kfreebsd.in | 8 +++++++- util/lvm.c | 9 +++------ 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6484cf826..19db47e04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-10-09 Robert Millan + + LVM support for FreeBSD and GNU/kFreeBSD. + + * util/lvm.c (grub_util_lvm_isvolume): Enable on FreeBSD and + GNU/kFreeBSD. + (LVM_DEV_MAPPER_STRING): Move from here ... + * include/grub/util/lvm.h (LVM_DEV_MAPPER_STRING): ... to here. + * util/getroot.c: Include `'. + (grub_util_get_dev_abstraction): Enable + grub_util_biosdisk_is_present() on FreeBSD and GNU/kFreeBSD. + Check for LVM abstraction on FreeBSD and GNU/kFreeBSD. + (grub_util_get_grub_dev): Replace "/dev/mapper/" with + `LVM_DEV_MAPPER_STRING'. Enable LVM and mdRAID only on platforms that + support it. + * util/grub-setup.c (main): Check for LVM also on FreeBSD and + GNU/kFreeBSD. + * util/grub.d/10_kfreebsd.in: Load `geom_linux_lvm' kernel module + when LVM abstraction is required for ${GRUB_DEVICE}. + 2011-10-06 Szymon Janc Add support for LZO compression in GRUB: diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h index 7a4c76c6b..ff268f83f 100644 --- a/include/grub/util/lvm.h +++ b/include/grub/util/lvm.h @@ -1,7 +1,7 @@ /* lvm.h - LVM support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,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 @@ -20,7 +20,14 @@ #ifndef GRUB_LVM_UTIL_HEADER #define GRUB_LVM_UTIL_HEADER 1 +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + #ifdef __linux__ +#define LVM_DEV_MAPPER_STRING "/dev/mapper/" +#else +#define LVM_DEV_MAPPER_STRING "/dev/linux_lvm/" +#endif + int grub_util_lvm_isvolume (char *name); #endif diff --git a/util/getroot.c b/util/getroot.c index 71064583f..7c5602e71 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1,7 +1,7 @@ /* getroot.c - Get root device */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,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 @@ -33,6 +33,7 @@ #include #include #include +#include #include #ifdef HAVE_DEVICE_MAPPER @@ -856,12 +857,14 @@ grub_util_get_geom_abstraction (const char *dev) int grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { -#ifdef __linux__ - enum grub_dev_abstraction_types ret; - +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* User explicitly claims that this drive is visible by BIOS. */ if (grub_util_biosdisk_is_present (os_dev)) return GRUB_DEV_ABSTRACTION_NONE; +#endif + +#ifdef __linux__ + enum grub_dev_abstraction_types ret; /* Check for LVM and LUKS. */ ret = grub_util_get_dm_abstraction (os_dev); @@ -880,6 +883,10 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) grub_util_info ("abstraction of %s is %s", os_dev, abs); if (abs && grub_strcasecmp (abs, "eli") == 0) return GRUB_DEV_ABSTRACTION_GELI; + + /* Check for LVM. */ + if (!strncmp (os_dev, LVM_DEV_MAPPER_STRING, sizeof(LVM_DEV_MAPPER_STRING)-1)) + return GRUB_DEV_ABSTRACTION_LVM; #endif /* No abstraction found. */ @@ -1111,11 +1118,12 @@ grub_util_get_grub_dev (const char *os_dev) switch (grub_util_get_dev_abstraction (os_dev)) { +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) case GRUB_DEV_ABSTRACTION_LVM: { unsigned short i, len; - grub_size_t offset = sizeof ("/dev/mapper/") - 1; + grub_size_t offset = sizeof (LVM_DEV_MAPPER_STRING) - 1; len = strlen (os_dev) - offset + 1; grub_dev = xmalloc (len + sizeof ("lvm/")); @@ -1191,7 +1199,9 @@ grub_util_get_grub_dev (const char *os_dev) } #endif break; +#endif +#ifdef __linux__ case GRUB_DEV_ABSTRACTION_RAID: if (os_dev[7] == '_' && os_dev[8] == 'd') @@ -1267,7 +1277,6 @@ grub_util_get_grub_dev (const char *os_dev) else grub_util_error ("unknown kind of RAID device `%s'", os_dev); -#ifdef __linux__ { char *mdadm_name = get_mdadm_uuid (os_dev); struct stat st; @@ -1292,9 +1301,8 @@ grub_util_get_grub_dev (const char *os_dev) free (mdadm_name); } } -#endif /* __linux__ */ - break; +#endif /* __linux__ */ default: /* GRUB_DEV_ABSTRACTION_NONE */ grub_dev = grub_util_biosdisk_get_grub_dev (os_dev); diff --git a/util/grub-setup.c b/util/grub-setup.c index 2505c03a4..b3a6c5c76 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -1,7 +1,7 @@ /* grub-setup.c - make GRUB usable */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,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 @@ -954,10 +954,12 @@ main (int argc, char *argv[]) arguments.dir ? : DEFAULT_DIRECTORY); } -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (grub_util_lvm_isvolume (root_dev)) must_embed = 1; +#endif +#ifdef __linux__ if (root_dev[0] == 'm' && root_dev[1] == 'd' && ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/')) { diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 2ade4ea35..e4bfc06cb 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -2,7 +2,7 @@ set -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010,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 @@ -98,6 +98,12 @@ EOF load_kfreebsd_module acpi true + for abstraction in dummy $(grub-probe -t abstraction --device ${GRUB_DEVICE}) ; do + case $abstraction in + lvm) load_kfreebsd_module geom_linux_lvm false ;; + esac + done + case "${kfreebsd_fs}" in zfs) load_kfreebsd_module opensolaris false diff --git a/util/lvm.c b/util/lvm.c index bb2c19fe3..0bc271e46 100644 --- a/util/lvm.c +++ b/util/lvm.c @@ -1,7 +1,7 @@ /* lvm.c - LVM support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,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 @@ -17,8 +17,7 @@ * along with GRUB. If not, see . */ -/* We only support LVM on Linux. */ -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #include #include @@ -26,8 +25,6 @@ #include #include -#define LVM_DEV_MAPPER_STRING "/dev/mapper/" - int grub_util_lvm_isvolume (char *name) { @@ -49,4 +46,4 @@ grub_util_lvm_isvolume (char *name) return 1; } -#endif /* ! __linux__ */ +#endif From 0eb8ffb1f579d4507d78a822c843e334417f9ba1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 19:16:37 +0200 Subject: [PATCH 055/315] * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. * include/grub/misc.h (grub_isxdigit): New function. * grub-core/video/colors.c (my_isxdigit): Removed. All users switched to grub_isxdigit. * grub-core/term/serial.c (grub_serial_find): Fix in case of port number starting with a letter. --- ChangeLog | 15 +++++++++++++++ grub-core/lib/posix_wrap/ctype.h | 3 +-- grub-core/term/serial.c | 2 +- grub-core/video/colors.c | 10 +--------- include/grub/misc.h | 6 ++++++ 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19db47e04..44882054c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-14 Vladimir Serbinenko + + * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. + * include/grub/misc.h (grub_isxdigit): New function. + * grub-core/video/colors.c (my_isxdigit): Removed. All users + switched to grub_isxdigit. + * grub-core/term/serial.c (grub_serial_find): Fix in case of port + number starting with a letter. + 2011-10-09 Robert Millan LVM support for FreeBSD and GNU/kFreeBSD. @@ -63,6 +72,12 @@ (grub_get_unaligned64): Likewise. * util/import_gcry.py (cryptolist): Add adler32. +2011-10-05 Vladimir Serbinenko + + * grub-core/Makefile.core.def: Eliminate rarely used emu_condition. This + in perspective decreases the complexity of build system and fixes + compilation right now. + 2011-10-01 Ales Nesrsta * grub-core/bus/usb/uhci.c: Changes made by Rock Cui - thanks! diff --git a/grub-core/lib/posix_wrap/ctype.h b/grub-core/lib/posix_wrap/ctype.h index 2dc3e53e9..9589778b6 100644 --- a/grub-core/lib/posix_wrap/ctype.h +++ b/grub-core/lib/posix_wrap/ctype.h @@ -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 diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index b724a945a..306694192 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -136,7 +136,7 @@ grub_serial_find (char *name) #ifndef GRUB_MACHINE_EMU if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 - && grub_isdigit (name [sizeof ("port") - 1])) + && grub_isxdigit (name [sizeof ("port") - 1])) { name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], 0, 16)); diff --git a/grub-core/video/colors.c b/grub-core/video/colors.c index 3119c0249..06625183e 100644 --- a/grub-core/video/colors.c +++ b/grub-core/video/colors.c @@ -211,14 +211,6 @@ grub_video_get_named_color (const char *name, return 0; } -static __inline int -my_isxdigit (char c) -{ - return ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F')); -} - static int parse_hex_color_component (const char *s, unsigned start, unsigned end) { @@ -267,7 +259,7 @@ grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) /* Count the hexits to determine the format. */ int hexits = 0; const char *end = s; - while (my_isxdigit (*end)) + while (grub_isxdigit (*end)) { end++; hexits++; diff --git a/include/grub/misc.h b/include/grub/misc.h index da4bd4a7e..66e74d8a8 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -136,6 +136,12 @@ grub_isdigit (int c) return (c >= '0' && c <= '9'); } +static inline int +grub_isxdigit (int c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + static inline int grub_isalnum (int c) { From c81296b65fad1d9bb4e5e2bb433719e5644827f0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 19:20:44 +0200 Subject: [PATCH 056/315] * grub-core/kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Don't assume that children of mapper nodes are mapper nodes. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 44882054c..3be8005a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-14 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Don't assume that children + of mapper nodes are mapper nodes. + 2011-10-14 Vladimir Serbinenko * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index a9a8c066e..23417a64d 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1416,7 +1416,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) if (tree) dm_tree_free (tree); free (path); - char *ret = grub_find_device ("/dev/mapper", + char *ret = grub_find_device ("/dev", (major << 8) | minor); return ret; } From d891955241a5976694738b63c752bb9e35d248a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 22:41:21 +0200 Subject: [PATCH 057/315] Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate types. (grub_hfsplus_btree_recoffset): Likewise. (grub_hfsplus_btree_recptr): Likewise. (grub_hfsplus_find_block): Likewise. (grub_hfsplus_btree_search): Likewise. (grub_hfsplus_read_block): Likewise. (grub_hfsplus_read_file): Likewise. (grub_hfsplus_mount): Likewise. (grub_hfsplus_btree_iterate_node): Likewise. (grub_hfsplus_btree_search): Likewise. (grub_hfsplus_iterate_dir): Likewise. (grub_hfsplus_read): A small code simplification. --- ChangeLog | 18 +++++++++++++++ grub-core/fs/hfsplus.c | 52 ++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3be8005a7..9a8b38fd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-10-14 Vladimir Serbinenko + + Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. + + * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate + types. + (grub_hfsplus_btree_recoffset): Likewise. + (grub_hfsplus_btree_recptr): Likewise. + (grub_hfsplus_find_block): Likewise. + (grub_hfsplus_btree_search): Likewise. + (grub_hfsplus_read_block): Likewise. + (grub_hfsplus_read_file): Likewise. + (grub_hfsplus_mount): Likewise. + (grub_hfsplus_btree_iterate_node): Likewise. + (grub_hfsplus_btree_search): Likewise. + (grub_hfsplus_iterate_dir): Likewise. + (grub_hfsplus_read): A small code simplification. + 2011-10-14 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 304b32126..245cd93a5 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -214,7 +214,7 @@ struct grub_fshelp_node struct grub_hfsplus_btree { grub_uint32_t root; - int nodesize; + grub_size_t nodesize; /* Catalog file node. */ struct grub_fshelp_node file; @@ -236,7 +236,7 @@ struct grub_hfsplus_data /* This is the offset into the physical disk for an embedded HFS+ filesystem (one inside a plain HFS wrapper). */ - int embedded_offset; + grub_disk_addr_t embedded_offset; int case_sensitive; }; @@ -245,7 +245,7 @@ static grub_dl_t my_mod; /* Return the offset of the record with the index INDEX, in the node NODE which is part of the B+ tree BTREE. */ -static inline unsigned int +static inline grub_off_t grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *node, int index) { @@ -263,7 +263,7 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *node, int index) { char *cnode = (char *) node; - unsigned int offset; + grub_off_t offset; offset = grub_hfsplus_btree_recoffset (btree, node, index); return (struct grub_hfsplus_key *) &cnode[offset]; } @@ -272,12 +272,12 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree, /* Find the extent that points to FILEBLOCK. If it is not in one of the 8 extents described by EXTENT, return -1. In that case set FILEBLOCK to the next block. */ -static int +static grub_disk_addr_t grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, - int *fileblock) + grub_disk_addr_t *fileblock) { int i; - grub_size_t blksleft = *fileblock; + grub_disk_addr_t blksleft = *fileblock; /* First lookup the file in the given extents. */ for (i = 0; i < 8; i++) @@ -288,7 +288,7 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, } *fileblock = blksleft; - return -1; + return 0xffffffffffffffffULL; } static grub_err_t @@ -296,7 +296,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, struct grub_hfsplus_key_internal *key, int (*compare_keys) (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb), - struct grub_hfsplus_btnode **matchnode, int *keyoffset); + struct grub_hfsplus_btnode **matchnode, + grub_off_t *keyoffset); static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb); @@ -307,15 +308,15 @@ static grub_disk_addr_t grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { struct grub_hfsplus_btnode *nnode = 0; - int blksleft = fileblock; + grub_disk_addr_t blksleft = fileblock; struct grub_hfsplus_extent *extents = &node->extents[0]; while (1) { struct grub_hfsplus_extkey *key; struct grub_hfsplus_extkey_internal extoverflow; - int blk; - int ptr; + grub_disk_addr_t blk; + grub_off_t ptr; /* Try to find this block in the current set of extents. */ blk = grub_hfsplus_find_block (extents, &blksleft); @@ -325,7 +326,7 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_free (nnode); nnode = 0; - if (blk != -1) + if (blk != 0xffffffffffffffffULL) return (blk + (node->data->embedded_offset >> (node->data->log2blksize - GRUB_DISK_SECTOR_BITS))); @@ -376,7 +377,7 @@ static grub_ssize_t grub_hfsplus_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_hfsplus_read_block, @@ -411,9 +412,9 @@ grub_hfsplus_mount (grub_disk_t disk) data->embedded_offset = 0; if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC) { - int extent_start; - int ablk_size; - int ablk_start; + grub_disk_addr_t extent_start; + grub_disk_addr_t ablk_size; + grub_disk_addr_t ablk_start; /* See if there's an embedded HFS+ filesystem. */ if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC) @@ -601,10 +602,10 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) static int grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *first_node, - int first_rec, + grub_disk_addr_t first_rec, int (*hook) (void *record)) { - int rec; + grub_disk_addr_t rec; for (;;) { @@ -642,12 +643,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, struct grub_hfsplus_key_internal *key, int (*compare_keys) (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb), - struct grub_hfsplus_btnode **matchnode, int *keyoffset) + struct grub_hfsplus_btnode **matchnode, + grub_off_t *keyoffset) { grub_uint64_t currnode; char *node; struct grub_hfsplus_btnode *nodedesc; - int rec; + grub_disk_addr_t rec; node = grub_malloc (btree->nodesize); if (! node) @@ -825,7 +827,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, struct grub_hfsplus_key_internal intern; struct grub_hfsplus_btnode *node; - int ptr; + grub_disk_addr_t ptr; /* Create a key that points to the first entry in the directory. */ intern.catkey.parent = dir->fileid; @@ -894,7 +896,6 @@ grub_hfsplus_close (grub_file_t file) return GRUB_ERR_NONE; } - /* Read LEN bytes data from FILE into BUF. */ static grub_ssize_t grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) @@ -902,13 +903,10 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) struct grub_hfsplus_data *data = (struct grub_hfsplus_data *) file->data; - int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook, + return grub_hfsplus_read_file (&data->opened_file, file->read_hook, file->offset, len, buf); - - return size; } - static grub_err_t grub_hfsplus_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, From 0017e5ef84cb4c7ac135254a52256d700e1c7dcb Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 15 Oct 2011 13:33:41 +0200 Subject: [PATCH 058/315] 2011-10-15 Robert Millan Fix build problem on FreeBSD and GNU/kFreeBSD. * util/getroot.c [__FreeBSD_kernel__]: Include `'. --- ChangeLog | 6 ++++++ util/getroot.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9a8b38fd0..723531f5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-15 Robert Millan + + Fix build problem on FreeBSD and GNU/kFreeBSD. + + * util/getroot.c [__FreeBSD_kernel__]: Include `'. + 2011-10-14 Vladimir Serbinenko Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. diff --git a/util/getroot.c b/util/getroot.c index 7c5602e71..510049acb 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -52,6 +52,10 @@ # include #endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +# include +#endif + #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) # include # include From 8bcebcb8e4cb75b0b6deffeb735c9fe26eb437b1 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 15 Oct 2011 18:37:55 +0200 Subject: [PATCH 059/315] 2011-10-15 Robert Millan * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. --- ChangeLog | 4 ++++ util/getroot.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 723531f5c..11b14ec28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-15 Robert Millan + + * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. + 2011-10-15 Robert Millan Fix build problem on FreeBSD and GNU/kFreeBSD. diff --git a/util/getroot.c b/util/getroot.c index 510049acb..3d6f9370c 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1137,7 +1137,9 @@ grub_util_get_grub_dev (const char *os_dev) } break; +#endif +#ifdef __linux__ case GRUB_DEV_ABSTRACTION_LUKS: { char *uuid, *dash; @@ -1152,9 +1154,10 @@ grub_util_get_grub_dev (const char *os_dev) grub_free (uuid); } break; +#endif - case GRUB_DEV_ABSTRACTION_GELI: #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) + case GRUB_DEV_ABSTRACTION_GELI: { char *whole; struct gmesh mesh; @@ -1201,7 +1204,6 @@ grub_util_get_grub_dev (const char *os_dev) } } } -#endif break; #endif From 3b619ae116833fa8624d72f4c83b9c8f266ab5a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:48:54 +0200 Subject: [PATCH 060/315] * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. (GRUB_XFS_INO_AGBITS): Make into inline function. (GRUB_XFS_INO_INOINAG): Likewise. (GRUB_XFS_INO_AG): Likewise. (GRUB_XFS_FSB_TO_BLOCK): Likewise. (GRUB_XFS_EXTENT_OFFSET): Likewise. (GRUB_XFS_EXTENT_BLOCK): Likewise. (GRUB_XFS_EXTENT_SIZE): Likewise. (GRUB_XFS_ROUND_TO_DIRENT): Likewise. (GRUB_XFS_NEXT_DIRENT): Likewise. (grub_xfs_read_block): Rewrite the btree parsing. Fixes invalid BMAP. (grub_xfs_read_file): Fix offset type. --- ChangeLog | 15 ++++++ grub-core/fs/xfs.c | 111 ++++++++++++++++++++++++++++++++------------- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 11b14ec28..abe19dc78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-10-16 Vladimir Serbinenko + + * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. + (GRUB_XFS_INO_AGBITS): Make into inline function. + (GRUB_XFS_INO_INOINAG): Likewise. + (GRUB_XFS_INO_AG): Likewise. + (GRUB_XFS_FSB_TO_BLOCK): Likewise. + (GRUB_XFS_EXTENT_OFFSET): Likewise. + (GRUB_XFS_EXTENT_BLOCK): Likewise. + (GRUB_XFS_EXTENT_SIZE): Likewise. + (GRUB_XFS_ROUND_TO_DIRENT): Likewise. + (GRUB_XFS_NEXT_DIRENT): Likewise. + (grub_xfs_read_block): Rewrite the btree parsing. Fixes invalid BMAP. + (grub_xfs_read_file): Fix offset type. + 2011-10-15 Robert Millan * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index eb0783407..3dc5e0af0 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -120,7 +120,9 @@ struct grub_xfs_inode grub_uint64_t nblocks; grub_uint32_t extsize; grub_uint32_t nextents; - grub_uint8_t unused3[20]; + grub_uint16_t unused3; + grub_uint8_t fork_offset; + grub_uint8_t unused4[17]; union { char raw[156]; @@ -154,7 +156,7 @@ struct grub_xfs_data grub_disk_t disk; int pos; int bsize; - int agsize; + grub_uint32_t agsize; struct grub_fshelp_node diropen; }; @@ -168,33 +170,67 @@ static grub_dl_t my_mod; #define FILETYPE_INO_DIRECTORY 0040000 #define FILETYPE_INO_SYMLINK 0120000 -#define GRUB_XFS_INO_AGBITS(data) \ - ((data)->sblock.log2_agblk + (data)->sblock.log2_inop) -#define GRUB_XFS_INO_INOINAG(data, ino) \ - (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)) -#define GRUB_XFS_INO_AG(data,ino) \ - (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)) +static inline int +GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data) +{ + return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop); +} -#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \ - (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \ - + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1))) +static inline grub_uint64_t +GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); +} -#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \ - ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \ - | grub_be_to_cpu32 (exts[ex][1]) >> 9) +static inline grub_uint64_t +GRUB_XFS_INO_AG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)); +} -#define GRUB_XFS_EXTENT_BLOCK(exts,ex) \ - ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \ - & (0x1ff)) << 43 \ - | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \ - | grub_be_to_cpu32 (exts[ex][3]) >> 21) +static inline grub_disk_addr_t +GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb) +{ + return ((fsb >> data->sblock.log2_agblk) * data->agsize + + (fsb & ((1LL << data->sblock.log2_agblk) - 1))); +} -#define GRUB_XFS_EXTENT_SIZE(exts,ex) \ - (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1)) +static inline grub_uint64_t +GRUB_XFS_EXTENT_OFFSET (grub_xfs_extent *exts, int ex) +{ + return ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 + | grub_be_to_cpu32 (exts[ex][1]) >> 9); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_BLOCK (grub_xfs_extent *exts, int ex) +{ + return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) + & (0x1ff)) << 43 + | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 + | grub_be_to_cpu32 (exts[ex][3]) >> 21); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex) +{ + return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1)); +} + +static inline int +GRUB_XFS_ROUND_TO_DIRENT (int pos) +{ + return ((((pos) + 8 - 1) / 8) * 8); +} + +static inline int +GRUB_XFS_NEXT_DIRENT (int pos, int len) +{ + return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2); +} -#define GRUB_XFS_ROUND_TO_DIRENT(pos) ((((pos) + 8 - 1) / 8) * 8) -#define GRUB_XFS_NEXT_DIRENT(pos,len) \ - (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2) static inline grub_uint64_t grub_xfs_inode_block (struct grub_xfs_data *data, @@ -250,13 +286,23 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) if (node->inode.format == XFS_INODE_FORMAT_BTREE) { grub_uint64_t *keys; + int recoffset; - leaf = grub_malloc (node->data->sblock.bsize); + leaf = grub_malloc (node->data->bsize); if (leaf == 0) return 0; nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); keys = &node->inode.data.btree.keys[0]; + if (node->inode.fork_offset) + recoffset = (node->inode.fork_offset + - ((char *) &node->inode.data.btree.keys - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); + else + recoffset = ((1 << node->data->sblock.log2_inode) + - ((char *) &node->inode.data.btree.keys + - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); do { int i; @@ -273,12 +319,9 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_free (leaf); return 0; } - if (grub_disk_read (node->data->disk, - grub_be_to_cpu64 (keys[i - 1 + nrec]) - << (node->data->sblock.log2_bsize - - GRUB_DISK_SECTOR_BITS), - 0, node->data->sblock.bsize, leaf)) + GRUB_XFS_FSB_TO_BLOCK (node->data, grub_be_to_cpu64 (keys[i - 1 + recoffset])) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), + 0, node->data->bsize, leaf)) return 0; if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) @@ -290,7 +333,11 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) nrec = grub_be_to_cpu16 (leaf->numrecs); keys = &leaf->keys[0]; - } while (leaf->level); + recoffset = ((node->data->bsize - ((char *) &leaf->keys + - (char *) leaf)) + / (2 * sizeof (grub_uint64_t))); + } + while (leaf->level); exts = (grub_xfs_extent *) keys; } else if (node->inode.format == XFS_INODE_FORMAT_EXT) @@ -336,7 +383,7 @@ static grub_ssize_t grub_xfs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_xfs_read_block, From 177b960ea44f146bb6b9e3c7be87bd3669b0d823 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:53:27 +0200 Subject: [PATCH 061/315] Fix python 3.x incompatibilities. * gentpl.py: Put brackets around print strings. * util/import_gcry.py: Open explicitly as utf-8. Use in instead of has_key. --- ChangeLog | 8 ++++++++ gentpl.py | 40 ++++++++++++++++++++-------------------- util/import_gcry.py | 28 +++++++++++++++------------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index abe19dc78..d5fbffcd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-16 Vladimir Serbinenko + + Fix python 3.x incompatibilities. + + * gentpl.py: Put brackets around print strings. + * util/import_gcry.py: Open explicitly as utf-8. + Use in instead of has_key. + 2011-10-16 Vladimir Serbinenko * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. diff --git a/gentpl.py b/gentpl.py index cb6b663d9..af210a040 100644 --- a/gentpl.py +++ b/gentpl.py @@ -568,28 +568,28 @@ f = script_rules() g = data_rules() z = global_variable_initializers() -print "[+ AutoGen5 template +]\n" +print ("[+ AutoGen5 template +]\n") for p in GRUB_PLATFORMS: - print define_macro_for_platform_sources(p) - print define_macro_for_platform_nodist_sources(p) + print (define_macro_for_platform_sources(p)) + print (define_macro_for_platform_nodist_sources(p)) # print define_macro_for_platform_dependencies(p) - print define_macro_for_platform_startup(p) - print define_macro_for_platform_cflags(p) - print define_macro_for_platform_ldadd(p) - print define_macro_for_platform_ldflags(p) - print define_macro_for_platform_cppflags(p) - print define_macro_for_platform_ccasflags(p) - print define_macro_for_platform_stripflags(p) - print define_macro_for_platform_objcopyflags(p) + print (define_macro_for_platform_startup(p)) + print (define_macro_for_platform_cflags(p)) + print (define_macro_for_platform_ldadd(p)) + print (define_macro_for_platform_ldflags(p)) + print (define_macro_for_platform_cppflags(p)) + print (define_macro_for_platform_ccasflags(p)) + print (define_macro_for_platform_stripflags(p)) + print (define_macro_for_platform_objcopyflags(p)) - print define_macro_for_platform_conditionals_if_statement(p) - print define_macro_for_platform_conditionals_endif_statement(p) + print (define_macro_for_platform_conditionals_if_statement(p)) + print (define_macro_for_platform_conditionals_endif_statement(p)) # print z # initializer for all vars -print a -print b -print c -print d -print e -print f -print g +print (a) +print (b) +print (c) +print (d) +print (e) +print (f) +print (g) diff --git a/util/import_gcry.py b/util/import_gcry.py index ee75b1b8e..720f19303 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -20,6 +20,7 @@ import re import sys import os import datetime +import codecs if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) @@ -40,9 +41,9 @@ except: print ("WARNING: %s already exists" % cipher_dir_out) cipher_files = os.listdir (cipher_dir_in) -conf = open (os.path.join ("grub-core", "Makefile.gcry.def"), "w") +conf = codecs.open (os.path.join ("grub-core", "Makefile.gcry.def"), "w", "utf-8") conf.write ("AutoGen definitions Makefile.tpl;\n\n") -confutil = open ("Makefile.utilgcry.def", "w") +confutil = codecs.open ("Makefile.utilgcry.def", "w", "utf-8") confutil.write ("AutoGen definitions Makefile.tpl;\n\n") confutil.write ("library = {\n"); confutil.write (" name = libgrubgcry.a;\n"); @@ -69,7 +70,7 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64, "_gcry_digest_spec_tiger" : 64, "_gcry_digest_spec_whirlpool" : 64} -cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w") +cryptolist = codecs.open (os.path.join (cipher_dir_out, "crypto.lst"), "w", "utf-8") # rijndael is the only cipher using aliases. So no need for mangling, just # hardcode it @@ -98,8 +99,8 @@ for cipher_file in cipher_files: nch = False if re.match (".*\.[ch]$", cipher_file): isc = re.match (".*\.c$", cipher_file) - f = open (infile, "r") - fw = open (outfile, "w") + f = codecs.open (infile, "r", "utf-8") + fw = codecs.open (outfile, "w", "utf-8") fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") @@ -125,6 +126,7 @@ for cipher_file in cipher_files: isglue = True modname = "gcry_%s" % modname for line in f: + line = line if skip_statement: if not re.search (";", line) is None: skip_statement = False @@ -151,7 +153,7 @@ for cipher_file in cipher_files: fw.write (" .modname = \"%s\",\n" % modname); fw.write ("#endif\n"); if ismd: - if not mdblocksizes.has_key (mdname): + if not (mdname in mdblocksizes): print ("ERROR: Unknown digest blocksize: %s\n" % mdname) exit (1) @@ -324,28 +326,28 @@ cryptolist.close () chlog = "%s * crypto.lst: New file.\n" % chlog outfile = os.path.join (cipher_dir_out, "types.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * types.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "memory.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") chlog = "%s * memory.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "cipher.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * cipher.h: Likewise.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "g10lib.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") chlog = "%s * g10lib.h: Likewise.\n" % chlog fw.close () @@ -355,7 +357,7 @@ outfile = os.path.join (cipher_dir_out, "ChangeLog") conf.close (); -initfile = open (os.path.join (cipher_dir_out, "init.c"), "w") +initfile = codecs.open (os.path.join (cipher_dir_out, "init.c"), "w", "utf-8") for module in modules: initfile.write ("extern void grub_%s_init (void);\n" % module) initfile.write ("extern void grub_%s_fini (void);\n" % module) @@ -380,8 +382,8 @@ confutil.write ("};\n"); confutil.close (); -f=open (infile, "r") -fw=open (outfile, "w") +f=codecs.open (infile, "r", "utf-8") +fw=codecs.open (outfile, "w", "utf-8") dt = datetime.date.today () fw.write ("%04d-%02d-%02d Automatic import tool\n" % \ (dt.year,dt.month, dt.day)) From 366e34fa5a49d022f3f01861c7d6ee6d7268a8a1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:57:48 +0200 Subject: [PATCH 062/315] Fix few obvious type discrepancies. * grub-core/fs/affs.c (grub_affs_read_file): Use grub_off_t for offset. * grub-core/fs/afs.c (grub_afs_read_file): Likewise. * grub-core/fs/fshelp.c (grub_fshelp_find_file): Remove leftover variable. * grub-core/fs/hfs.c (grub_hfs_read_file): Use grub_off_t for offset and connected types. * grub-core/fs/nilfs2.c (grub_nilfs2_read_file): Use grub_off_t for offset. (grub_nilfs2_iterate_dir): Use grub_off_t for fpos. * grub-core/fs/sfs.c (grub_sfs_read_file): Use grub_off_t for offset. * grub-core/fs/ufs.c (grub_ufs_read_file): Use grub_off_t for offset and connected types. --- ChangeLog | 17 +++++++++++++++++ grub-core/fs/affs.c | 2 +- grub-core/fs/afs.c | 2 +- grub-core/fs/fshelp.c | 1 - grub-core/fs/hfs.c | 24 +++++++++++++----------- grub-core/fs/nilfs2.c | 4 ++-- grub-core/fs/sfs.c | 2 +- grub-core/fs/ufs.c | 23 +++++++++++++---------- 8 files changed, 48 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5fbffcd4..2e44b4c26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-10-16 Vladimir Serbinenko + + Fix few obvious type discrepancies. + + * grub-core/fs/affs.c (grub_affs_read_file): Use grub_off_t for offset. + * grub-core/fs/afs.c (grub_afs_read_file): Likewise. + * grub-core/fs/fshelp.c (grub_fshelp_find_file): Remove leftover + variable. + * grub-core/fs/hfs.c (grub_hfs_read_file): Use grub_off_t for offset + and connected types. + * grub-core/fs/nilfs2.c (grub_nilfs2_read_file): Use grub_off_t for + offset. + (grub_nilfs2_iterate_dir): Use grub_off_t for fpos. + * grub-core/fs/sfs.c (grub_sfs_read_file): Use grub_off_t for offset. + * grub-core/fs/ufs.c (grub_ufs_read_file): Use grub_off_t for offset + and connected types. + 2011-10-16 Vladimir Serbinenko Fix python 3.x incompatibilities. diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index e17540e2f..adf2932bd 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -160,7 +160,7 @@ static grub_ssize_t grub_affs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_affs_read_block, diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index 35ef49937..b64ebb52c 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -336,7 +336,7 @@ static grub_ssize_t grub_afs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_afs_read_block, diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c index 2ff78c423..275cb9e1b 100644 --- a/grub-core/fs/fshelp.c +++ b/grub-core/fs/fshelp.c @@ -61,7 +61,6 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, char fpath[grub_strlen (currpath) + 1]; char *name = fpath; char *next; - // unsigned int pos = 0; enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; grub_fshelp_node_t currnode = currroot; grub_fshelp_node_t oldnode = currroot; diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index 6f27c69c4..973a2d2ef 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -244,22 +244,24 @@ static grub_ssize_t grub_hfs_read_file (struct grub_hfs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { - int i; - int blockcnt; + grub_off_t i; + grub_off_t blockcnt; - blockcnt = ((len + pos) - + data->blksz - 1) / data->blksz; + blockcnt = grub_divmod64 (((len + pos) + + data->blksz - 1), data->blksz, 0); - for (i = pos / data->blksz; i < blockcnt; i++) + for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++) { - int blknr; - int blockoff = pos % data->blksz; - int blockend = data->blksz; + grub_disk_addr_t blknr; + grub_off_t blockoff; + grub_off_t blockend = data->blksz; int skipfirst = 0; + grub_divmod64 (pos, data->blksz, &blockoff); + blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1); if (grub_errno) return -1; @@ -267,7 +269,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % data->blksz; + grub_divmod64 ((len + pos), data->blksz, &blockend); /* The last portion is exactly EXT2_BLOCK_SIZE (data). */ if (! blockend) @@ -275,7 +277,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, } /* First block. */ - if (i == pos / data->blksz) + if (i == grub_divmod64 (pos, data->blksz, 0)) { skipfirst = blockoff; blockend -= skipfirst; diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 44fb213bd..62cf167c7 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -628,7 +628,7 @@ grub_nilfs2_read_file (grub_fshelp_node_t node, sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_nilfs2_read_block, @@ -866,7 +866,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node)) { - unsigned int fpos = 0; + grub_off_t fpos = 0; struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; if (!diro->inode_read) diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 19ae90715..f1e09ccbd 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -250,7 +250,7 @@ static grub_ssize_t grub_sfs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_sfs_read_block, diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 0f4ea0019..435fec6a5 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -285,26 +285,29 @@ static grub_ssize_t grub_ufs_read_file (struct grub_ufs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { struct grub_ufs_sblock *sblock = &data->sblock; - int i; - int blockcnt; + grub_off_t i; + grub_off_t blockcnt; /* Adjust len so it we can't read past the end of the file. */ if (len + pos > INODE_SIZE (data)) len = INODE_SIZE (data) - pos; - blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock); + blockcnt = grub_divmod64 ((len + pos + UFS_BLKSZ (sblock) - 1), + UFS_BLKSZ (sblock), 0); - for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++) + for (i = grub_divmod64 (pos, UFS_BLKSZ (sblock), 0); i < blockcnt; i++) { - int blknr; - int blockoff = pos % UFS_BLKSZ (sblock); - int blockend = UFS_BLKSZ (sblock); + grub_disk_addr_t blknr; + grub_off_t blockoff; + grub_off_t blockend = UFS_BLKSZ (sblock); int skipfirst = 0; + grub_divmod64 (pos, UFS_BLKSZ (sblock), &blockoff); + blknr = grub_ufs_get_file_block (data, i); if (grub_errno) return -1; @@ -312,14 +315,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % UFS_BLKSZ (sblock); + grub_divmod64 (len + pos, UFS_BLKSZ (sblock), &blockend); if (!blockend) blockend = UFS_BLKSZ (sblock); } /* First block. */ - if (i == (pos / (int) UFS_BLKSZ (sblock))) + if (i == grub_divmod64 (pos, UFS_BLKSZ (sblock), 0)) { skipfirst = blockoff; blockend -= skipfirst; From 2afb7f6cbf5ca5c49750c70b07f67d4733f66061 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 15:15:35 +0200 Subject: [PATCH 063/315] * configure.ac: Check for __ctzdi2 and __ctzsi2. * include/grub/libgcc.h: Include __ctzdi2 and __ctzsi2 if present. --- ChangeLog | 5 +++++ configure.ac | 2 +- include/grub/libgcc.h | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2e44b4c26..0592459c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-16 Vladimir Serbinenko + + * configure.ac: Check for __ctzdi2 and __ctzsi2. + * include/grub/libgcc.h: Include __ctzdi2 and __ctzsi2 if present. + 2011-10-16 Vladimir Serbinenko Fix few obvious type discrepancies. diff --git a/configure.ac b/configure.ac index 9cfbd2340..6aafdf13d 100644 --- a/configure.ac +++ b/configure.ac @@ -587,7 +587,7 @@ CFLAGS="$CFLAGS -Wl,--defsym,abort=main" fi # Check for libgcc symbols -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2) if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index 19723fd23..7a433dc68 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -63,6 +63,12 @@ void EXPORT_FUNC (__divsi3) (void); # ifdef HAVE___MODSI3 void EXPORT_FUNC (__modsi3) (void); # endif +# ifdef HAVE___CTZDI2 +void EXPORT_FUNC (__ctzdi2) (void); +# endif +# ifdef HAVE___CTZSI2 +void EXPORT_FUNC (__ctzsi2) (void); +# endif #endif # ifdef HAVE___IA64_TRAMPOLINE From 39705fadd7ed2d4f78df6f48abc13150464a5698 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 15:23:29 +0200 Subject: [PATCH 064/315] Replace grub_module_iterate with FOR_MODULES. * grub-core/disk/memdisk.c (GRUB_MOD_INIT): Switched to new interface. * grub-core/kern/efi/efi.c (grub_arch_modules_addr): Renamed to... (grub_efi_modules_addr): ...this. * grub-core/kern/efi/init.c (grub_modbase): New variable. (grub_efi_init): Set grub_modbase. * grub-core/kern/emu/main.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. * grub-core/kern/i386/coreboot/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/i386/pc/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/ieee1275/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/main.c (grub_module_iterate): Remove. (grub_modules_get_end): Use grub_modbase. (grub_load_modules): Use FOR_MODULES. (grub_load_config): Likewise. * grub-core/kern/mips/arc/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * include/grub/efi/efi.h (grub_efi_modules_addr): New declaration. * include/grub/kernel.h (grub_arch_modules_addr): Removed. (grub_module_iterate): Likewise. (grub_modbase): New variable declaration. (FOR_MODULES): New macro. --- ChangeLog | 40 ++++++++++++++ grub-core/disk/memdisk.c | 34 +++++------- grub-core/kern/efi/efi.c | 2 +- grub-core/kern/efi/init.c | 3 + grub-core/kern/emu/main.c | 6 +- grub-core/kern/i386/coreboot/init.c | 19 +++---- grub-core/kern/i386/pc/init.c | 13 ++--- grub-core/kern/ieee1275/init.c | 11 ++-- grub-core/kern/main.c | 83 +++++++++------------------- grub-core/kern/mips/arc/init.c | 8 +-- grub-core/kern/mips/loongson/init.c | 6 +- grub-core/kern/mips/qemu_mips/init.c | 6 +- include/grub/efi/efi.h | 2 + include/grub/kernel.h | 10 +++- 14 files changed, 117 insertions(+), 126 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0592459c3..2ce132a14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2011-10-16 Vladimir Serbinenko + + Replace grub_module_iterate with FOR_MODULES. + + * grub-core/disk/memdisk.c (GRUB_MOD_INIT): Switched to new interface. + * grub-core/kern/efi/efi.c (grub_arch_modules_addr): Renamed to... + (grub_efi_modules_addr): ...this. + * grub-core/kern/efi/init.c (grub_modbase): New variable. + (grub_efi_init): Set grub_modbase. + * grub-core/kern/emu/main.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + * grub-core/kern/i386/coreboot/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/i386/pc/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/ieee1275/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/main.c (grub_module_iterate): Remove. + (grub_modules_get_end): Use grub_modbase. + (grub_load_modules): Use FOR_MODULES. + (grub_load_config): Likewise. + * grub-core/kern/mips/arc/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): + Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * include/grub/efi/efi.h (grub_efi_modules_addr): New declaration. + * include/grub/kernel.h (grub_arch_modules_addr): Removed. + (grub_module_iterate): Likewise. + (grub_modbase): New variable declaration. + (FOR_MODULES): New macro. + 2011-10-16 Vladimir Serbinenko * configure.ac: Check for __ctzdi2 and __ctzsi2. diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index ed570c6a0..4de0971ae 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -86,30 +86,24 @@ static struct grub_disk_dev grub_memdisk_dev = GRUB_MOD_INIT(memdisk) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - if (header->type == OBJ_TYPE_MEMDISK) - { - char *memdisk_orig_addr; - memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); + struct grub_module_header *header; + FOR_MODULES (header) + if (header->type == OBJ_TYPE_MEMDISK) + { + char *memdisk_orig_addr; + memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); - grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); + grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); - memdisk_size = header->size - sizeof (struct grub_module_header); - memdisk_addr = grub_malloc (memdisk_size); + memdisk_size = header->size - sizeof (struct grub_module_header); + memdisk_addr = grub_malloc (memdisk_size); - grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); - grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); + grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); + grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); - grub_disk_dev_register (&grub_memdisk_dev); - return 1; - } - - return 0; - } - - grub_module_iterate (hook); + grub_disk_dev_register (&grub_memdisk_dev); + break; + } } GRUB_MOD_FINI(memdisk) diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index d0994a940..e27dd1ad0 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -218,7 +218,7 @@ grub_get_rtc (void) /* Search the mods section from the PE32/PE32+ image. This code uses a PE32 header, but should work with PE32+ as well. */ grub_addr_t -grub_arch_modules_addr (void) +grub_efi_modules_addr (void) { grub_efi_loaded_image_t *image; struct grub_pe32_header *header; diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 4dfb06284..942ab0256 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -26,9 +26,12 @@ #include #include +grub_addr_t grub_modbase; + void grub_efi_init (void) { + grub_modbase = grub_efi_modules_addr (); /* First of all, initialize the console so that GRUB can display messages. */ grub_console_init (); diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 9a58acd9e..d5c09ad47 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -53,11 +53,7 @@ static char *root_dev = NULL, *dir = NULL; int grub_no_autoload; -grub_addr_t -grub_arch_modules_addr (void) -{ - return 0; -} +grub_addr_t grub_modbase = 0; void grub_reboot (void) diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index ebbea2523..b7510ff98 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -56,10 +56,18 @@ grub_exit (void) grub_cpu_idle (); } +#ifdef GRUB_MACHINE_QEMU +grub_addr_t grub_modbase; +#else +grub_addr_t grub_modbase = ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); +#endif + void grub_machine_init (void) { #ifdef GRUB_MACHINE_QEMU + grub_modbase = grub_core_entry_addr + grub_kernel_image_size; + grub_qemu_init_cirrus (); #endif /* Initialize the console as early as possible. */ @@ -118,14 +126,3 @@ grub_machine_fini (void) grub_vga_text_fini (); grub_stop_floppy (); } - -/* Return the end of the core image. */ -grub_addr_t -grub_arch_modules_addr (void) -{ -#ifdef GRUB_MACHINE_QEMU - return grub_core_entry_addr + grub_kernel_image_size; -#else - return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); -#endif -} diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 24fe8fed9..62269de78 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -129,6 +129,8 @@ compact_mem_regions (void) } } +grub_addr_t grub_modbase; + void grub_machine_init (void) { @@ -137,6 +139,9 @@ grub_machine_init (void) int grub_lower_mem; #endif + grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + /* Initialize the console as early as possible. */ grub_console_init (); @@ -206,11 +211,3 @@ grub_machine_fini (void) grub_console_fini (); grub_stop_floppy (); } - -/* Return the end of the core image. */ -grub_addr_t -grub_arch_modules_addr (void) -{ - return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -} diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 81b06c88e..76f932d09 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -256,9 +256,14 @@ grub_parse_cmdline (void) static grub_uint64_t ieee1275_get_time_ms (void); +grub_addr_t grub_modbase; + void grub_machine_init (void) { + grub_modbase = ALIGN_UP((grub_addr_t) _end + + GRUB_KERNEL_MACHINE_MOD_GAP, + GRUB_KERNEL_MACHINE_MOD_ALIGN); grub_ieee1275_init (); grub_console_init_early (); @@ -293,9 +298,3 @@ grub_get_rtc (void) { return ieee1275_get_time_ms (); } - -grub_addr_t -grub_arch_modules_addr (void) -{ - return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); -} diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 0cec93d89..9e1971773 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -30,45 +30,20 @@ #include #include -void -grub_module_iterate (int (*hook) (struct grub_module_header *header)) -{ - struct grub_module_info *modinfo; - struct grub_module_header *header; - grub_addr_t modbase; - - modbase = grub_arch_modules_addr (); - modinfo = (struct grub_module_info *) modbase; - - /* Check if there are any modules. */ - if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return; - - for (header = (struct grub_module_header *) (modbase + modinfo->offset); - header < (struct grub_module_header *) (modbase + modinfo->size); - header = (struct grub_module_header *) ((char *) header + header->size)) - { - if (hook (header)) - break; - } -} - /* This is actualy platform-independant but used only on loongson and sparc. */ #if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) grub_addr_t grub_modules_get_end (void) { struct grub_module_info *modinfo; - grub_addr_t modbase; - modbase = grub_arch_modules_addr (); - modinfo = (struct grub_module_info *) modbase; + modinfo = (struct grub_module_info *) grub_modbase; /* Check if there are any modules. */ if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return modbase; + return grub_modbase; - return modbase + modinfo->size; + return grub_modbase + modinfo->size; } #endif @@ -76,42 +51,36 @@ grub_modules_get_end (void) static void grub_load_modules (void) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - /* Not an ELF module, skip. */ - if (header->type != OBJ_TYPE_ELF) - return 0; + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an ELF module, skip. */ + if (header->type != OBJ_TYPE_ELF) + continue; - if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), - (header->size - sizeof (struct grub_module_header)))) - grub_fatal ("%s", grub_errmsg); + if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), + (header->size - sizeof (struct grub_module_header)))) + grub_fatal ("%s", grub_errmsg); - if (grub_errno) - grub_print_error (); - - return 0; - } - - grub_module_iterate (hook); + if (grub_errno) + grub_print_error (); + } } static void grub_load_config (void) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - /* Not an embedded config, skip. */ - if (header->type != OBJ_TYPE_CONFIG) - return 0; - - grub_parser_execute ((char *) header + - sizeof (struct grub_module_header)); - return 1; - } - - grub_module_iterate (hook); + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an embedded config, skip. */ + if (header->type != OBJ_TYPE_CONFIG) + continue; + + grub_parser_execute ((char *) header + + sizeof (struct grub_module_header)); + break; + } } /* Write hook for the environment variables of root. Remove surrounding diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 514b481f6..2e25335ca 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -125,12 +125,14 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) } extern grub_uint32_t grub_total_modules_size; +grub_addr_t grub_modbase; void grub_machine_init (void) { struct grub_arc_memory_descriptor *cur = NULL; + grub_modbase = GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size; grub_console_init_early (); /* FIXME: measure this. */ @@ -164,12 +166,6 @@ grub_machine_init (void) grub_arcdisk_init (); } -grub_addr_t -grub_arch_modules_addr (void) -{ - return GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size; -} - void grub_machine_fini (void) { diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 2d1a0653e..8acfb0767 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -298,9 +298,5 @@ grub_reboot (void) } extern char _end[]; +grub_addr_t grub_modbase = (grub_addr_t) _end; -grub_addr_t -grub_arch_modules_addr (void) -{ - return (grub_addr_t) _end; -} diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index db9cc796a..4921c42bf 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -113,9 +113,5 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) } extern char _end[]; +grub_addr_t grub_modbase = (grub_addr_t) _end; -grub_addr_t -grub_arch_modules_addr (void) -{ - return (grub_addr_t) _end; -} diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index e98f99507..7ecda58ab 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -70,6 +70,8 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, char **device, char **path); +grub_addr_t grub_efi_modules_addr (void); + void grub_efi_mm_init (void); void grub_efi_mm_fini (void); void grub_efi_init (void); diff --git a/include/grub/kernel.h b/include/grub/kernel.h index aef585668..d8c0fed33 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -68,9 +68,15 @@ struct grub_module_info64 #define grub_module_info grub_module_info32 #endif -extern grub_addr_t grub_arch_modules_addr (void); +extern grub_addr_t EXPORT_VAR (grub_modbase); -extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); +#define FOR_MODULES(var) for (\ + var = grub_modbase ? (struct grub_module_header *) \ + (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ + ((char *) var + ((struct grub_module_header *) var)->size)) grub_addr_t grub_modules_get_end (void); From a97501d2389d524323293395636b43aec73f1761 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Oct 2011 15:21:51 +0200 Subject: [PATCH 065/315] Make grub_prefix into module to fix the arbitrary limit and save some space. * grub-core/kern/emu/main.c (grub_prefix): Removed. * grub-core/kern/i386/coreboot/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/efi/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/ieee1275/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/pc/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/qemu/startup.S (grub_prefix): Likewise. * grub-core/kern/ia64/efi/startup.S (grub_prefix): Likewise. * grub-core/kern/mips/startup.S (grub_prefix): Likewise. * grub-core/kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. * grub-core/kern/sparc64/ieee1275/crt0.S (grub_prefix): Likewise. * grub-core/kern/x86_64/efi/startup.S (grub_prefix): Likewise. * include/grub/ia64/efi/kernel.h: Removed. * include/grub/kernel.h: New module type OBJ_TYPE_PREFIX. (grub_prefix): Removed. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_PREFIX): Removed. (GRUB_KERNEL_I386_PC_PREFIX_END): Likewise. (GRUB_KERNEL_I386_QEMU_PREFIX): Likewise. (GRUB_KERNEL_I386_QEMU_PREFIX_END): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_LOONGSON_PREFIX): Likewise. (GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. (GRUB_KERNEL_I386_EFI_PREFIX): Likewise. (GRUB_KERNEL_I386_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_IA64_EFI_PREFIX): Likewise. (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_X86_64_EFI_PREFIX): Likewise. (GRUB_KERNEL_X86_64_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_I386_COREBOOT_PREFIX): Likewise. (GRUB_KERNEL_I386_COREBOOT_PREFIX_END): Likewise. (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): Likewise. (GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END): Likewise. (GRUB_KERNEL_I386_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_I386_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_MACHINE_PREFIX): Likewise. (GRUB_KERNEL_MACHINE_PREFIX_END): Likewise. * grub-core/kern/main.c (grub_set_prefix_and_root): Retrieve grub_prefix from module. * util/grub-mkimage.c (image_target_desc): Removed prefix and prefix_end. (image_targets): Likewise. (generate_image): Put prefix as a module. --- ChangeLog | 54 ++++++++++++++++++ grub-core/kern/emu/main.c | 2 - grub-core/kern/i386/coreboot/startup.S | 15 ----- grub-core/kern/i386/efi/startup.S | 11 ---- grub-core/kern/i386/ieee1275/startup.S | 18 ------ grub-core/kern/i386/pc/startup.S | 11 ---- grub-core/kern/i386/qemu/startup.S | 8 --- grub-core/kern/ia64/efi/startup.S | 10 ---- grub-core/kern/main.c | 49 +++++++++------- grub-core/kern/mips/startup.S | 11 ---- grub-core/kern/powerpc/ieee1275/startup.S | 14 ----- grub-core/kern/sparc64/ieee1275/crt0.S | 8 --- grub-core/kern/x86_64/efi/startup.S | 15 ----- include/grub/ia64/efi/kernel.h | 34 ------------ include/grub/kernel.h | 8 +-- include/grub/offsets.h | 53 ------------------ util/grub-mkimage.c | 68 ++++++++--------------- 17 files changed, 106 insertions(+), 283 deletions(-) delete mode 100644 include/grub/ia64/efi/kernel.h diff --git a/ChangeLog b/ChangeLog index 2ce132a14..a758fc275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +2011-10-18 Vladimir Serbinenko + + Make grub_prefix into module to fix the arbitrary limit and save + some space. + + * grub-core/kern/emu/main.c (grub_prefix): Removed. + * grub-core/kern/i386/coreboot/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/efi/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/ieee1275/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/pc/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/qemu/startup.S (grub_prefix): Likewise. + * grub-core/kern/ia64/efi/startup.S (grub_prefix): Likewise. + * grub-core/kern/mips/startup.S (grub_prefix): Likewise. + * grub-core/kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. + * grub-core/kern/sparc64/ieee1275/crt0.S (grub_prefix): Likewise. + * grub-core/kern/x86_64/efi/startup.S (grub_prefix): Likewise. + * include/grub/ia64/efi/kernel.h: Removed. + * include/grub/kernel.h: New module type OBJ_TYPE_PREFIX. + (grub_prefix): Removed. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_PREFIX): Removed. + (GRUB_KERNEL_I386_PC_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_QEMU_PREFIX): Likewise. + (GRUB_KERNEL_I386_QEMU_PREFIX_END): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_LOONGSON_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_EFI_PREFIX): Likewise. + (GRUB_KERNEL_I386_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_IA64_EFI_PREFIX): Likewise. + (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_X86_64_EFI_PREFIX): Likewise. + (GRUB_KERNEL_X86_64_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_COREBOOT_PREFIX): Likewise. + (GRUB_KERNEL_I386_COREBOOT_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): Likewise. + (GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_I386_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_MACHINE_PREFIX): Likewise. + (GRUB_KERNEL_MACHINE_PREFIX_END): Likewise. + * grub-core/kern/main.c (grub_set_prefix_and_root): Retrieve grub_prefix + from module. + * util/grub-mkimage.c (image_target_desc): Removed prefix and + prefix_end. + (image_targets): Likewise. + (generate_image): Put prefix as a module. + 2011-10-16 Vladimir Serbinenko Replace grub_module_iterate with FOR_MODULES. diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index d5c09ad47..8d15f17c5 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -79,8 +79,6 @@ grub_machine_fini (void) grub_console_fini (); } -char grub_prefix[64] = ""; - static struct option options[] = diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index 07c5437c0..5e7767bb9 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -40,21 +40,6 @@ start: _start: jmp codestart - /* - * This is a special data area at a fixed offset from the beginning. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END - /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). */ diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 5b464ab83..49b05c1e6 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -41,17 +41,6 @@ _start: * This is a special data area 8 bytes from the beginning. */ - . = _start + 0x8 - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + 0x50 - codestart: /* * EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack. diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 82087323b..6b39f5f3a 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -36,24 +36,6 @@ start: _start: - jmp codestart - - /* - * This is a special data area at a fixed offset from the beginning. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END - -codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) jmp EXT_C(grub_main) diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 0fe114add..3bbe34753 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -455,17 +455,6 @@ gate_a20_check_state: */ . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE - . = _start + GRUB_KERNEL_MACHINE_PREFIX -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END - - - /* * grub_exit() * diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 7834d1df5..6500de620 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -34,14 +34,6 @@ VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) .long 0 -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Relocate to low memory. First we figure out our location. diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S index b5e26a204..d75c6d7cc 100644 --- a/grub-core/kern/ia64/efi/startup.S +++ b/grub-core/kern/ia64/efi/startup.S @@ -42,13 +42,3 @@ _start: br.ret.sptk.few rp .endp _start - - . = _start + GRUB_KERNEL_MACHINE_PREFIX -VARIABLE(grub_prefix) - .byte 0 - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 9e1971773..77be11422 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -105,25 +105,32 @@ grub_set_prefix_and_root (void) char *path = NULL; char *fwdevice = NULL; char *fwpath = NULL; + char *prefix; + struct grub_module_header *header; + + FOR_MODULES (header) + if (header->type == OBJ_TYPE_PREFIX) + prefix = (char *) header + sizeof (struct grub_module_header); grub_register_variable_hook ("root", 0, grub_env_write_root); - { - char *pptr = NULL; - if (grub_prefix[0] == '(') - { - pptr = grub_strrchr (grub_prefix, ')'); - if (pptr) - { - device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); - pptr++; - } - } - if (!pptr) - pptr = grub_prefix; - if (pptr[0]) - path = grub_strdup (pptr); - } + if (prefix) + { + char *pptr = NULL; + if (prefix[0] == '(') + { + pptr = grub_strrchr (prefix, ')'); + if (pptr) + { + device = grub_strndup (prefix + 1, pptr - prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } if ((!device || device[0] == ',' || !device[0]) || !path) grub_machine_get_bootlocation (&fwdevice, &fwpath); @@ -152,13 +159,13 @@ grub_set_prefix_and_root (void) path = fwpath; if (device) { - char *prefix; + char *prefix_set; - prefix = grub_xasprintf ("(%s)%s", device, path ? : ""); - if (prefix) + prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); + if (prefix_set) { - grub_env_set ("prefix", prefix); - grub_free (prefix); + grub_env_set ("prefix", prefix_set); + grub_free (prefix_set); } grub_env_set ("root", device); } diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index da6450237..2476038bc 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -40,17 +40,6 @@ start: VARIABLE(grub_total_modules_size) .long 0 - . = _start + GRUB_KERNEL_MACHINE_PREFIX - -VARIABLE(grub_prefix) - - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END VARIABLE (grub_arch_busclock) .long 0 VARIABLE (grub_arch_cpuclock) diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 0b1c23346..b26c47edb 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -28,20 +28,6 @@ .globl start, _start start: _start: - b codestart - - . = _start + GRUB_KERNEL_MACHINE_PREFIX - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END - -codestart: li 2, 0 li 13, 0 diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index cebdca2b6..1466a56f8 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -35,14 +35,6 @@ VARIABLE(grub_kernel_image_size) .word 0 VARIABLE(grub_compressed_size) .word 0 -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = EXT_C(_start) + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Copy the modules past the end of the kernel image. diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index fb4fc7b64..37efde7fc 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -39,21 +39,6 @@ _start: . = _start + 0x6 .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - /* - * This is a special data area 8 bytes from the beginning. - */ - - . = _start + 0x8 - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + 0x50 - codestart: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) diff --git a/include/grub/ia64/efi/kernel.h b/include/grub/ia64/efi/kernel.h deleted file mode 100644 index ae75380f0..000000000 --- a/include/grub/ia64/efi/kernel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007,2008,2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - -#ifndef ASM_FILE -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; -#endif - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index d8c0fed33..2ff6b2469 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -26,7 +26,8 @@ enum { OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX }; /* The module header. */ @@ -98,9 +99,4 @@ void grub_register_exported_symbols (void); extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); - -#if ! defined (ASM_FILE) -extern char grub_prefix[]; -#endif - #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index e8170fcbe..526cfee68 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -42,12 +42,6 @@ #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x730 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE - -/* End of the data section. */ -#define GRUB_KERNEL_I386_PC_PREFIX_END (GRUB_KERNEL_I386_PC_PREFIX + 0x40) - /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 @@ -66,12 +60,6 @@ /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_I386_QEMU_PREFIX_END 0x50 - #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 /* The offset of GRUB_TOTAL_MODULE_SIZE. */ @@ -83,20 +71,12 @@ /* The offset of GRUB_COMPRESSED_SIZE. */ #define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END 0x114 - #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 #define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 -#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 -#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 @@ -109,8 +89,6 @@ #define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END 0x54 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR 0x80200000 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN 32 @@ -118,8 +96,6 @@ #define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc #define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END 0x54 #define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8bd00000 @@ -130,36 +106,9 @@ #define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_ARC_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_ARC_PREFIX_END 0x54 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_EFI_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_I386_EFI_PREFIX_END 0x50 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_IA64_EFI_PREFIX 0x50 - -/* End of the data section. */ -#define GRUB_KERNEL_IA64_EFI_PREFIX_END 0xa0 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_X86_64_EFI_PREFIX_END 0x50 - -#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 -#define GRUB_KERNEL_I386_COREBOOT_PREFIX_END 0x42 #define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 -#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX GRUB_KERNEL_I386_COREBOOT_PREFIX -#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END GRUB_KERNEL_I386_COREBOOT_PREFIX_END - -#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 -#define GRUB_KERNEL_I386_IEEE1275_PREFIX_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 #define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 @@ -194,8 +143,6 @@ #define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) #define GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) -#define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX) -#define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _PREFIX_END) #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) #define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 420690923..4440fdd12 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -77,8 +77,6 @@ struct image_target_desc PLATFORM_FLAGS_DECOMPRESSORS = 2, PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, } flags; - unsigned prefix; - unsigned prefix_end; unsigned raw_size; unsigned total_module_size; unsigned kernel_image_size; @@ -110,8 +108,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, - .prefix_end = GRUB_KERNEL_I386_COREBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -133,8 +129,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_MULTIBOOT_PREFIX, - .prefix_end = GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -156,8 +150,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_PC, .flags = PLATFORM_FLAGS_LZMA, - .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -175,8 +167,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_PC_PXE, .flags = PLATFORM_FLAGS_LZMA, - .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -194,8 +184,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_EFI_PREFIX, - .prefix_end = GRUB_KERNEL_I386_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -219,8 +207,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_I386_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -242,8 +228,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, - .prefix_end = GRUB_KERNEL_I386_QEMU_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, @@ -261,8 +245,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, - .prefix_end = GRUB_KERNEL_X86_64_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -281,8 +263,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -303,8 +283,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -327,8 +305,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -349,8 +325,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -372,8 +346,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -391,8 +363,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -410,8 +380,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_IA64_EFI_PREFIX, - .prefix_end = GRUB_KERNEL_IA64_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -431,8 +399,6 @@ struct image_target_desc image_targets[] = .id = IMAGE_MIPS_ARC, .flags = (PLATFORM_FLAGS_DECOMPRESSORS | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), - .prefix = GRUB_KERNEL_MIPS_ARC_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_ARC_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -453,8 +419,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -475,8 +439,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -497,8 +459,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -519,8 +479,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -797,6 +755,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; size_t memdisk_size = 0, config_size = 0, config_size_pure = 0; + size_t prefix_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; @@ -833,6 +792,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size += config_size + sizeof (struct grub_module_header); } + if (prefix) + { + prefix_size = ALIGN_ADDR (strlen (prefix) + 1); + total_module_size += prefix_size + sizeof (struct grub_module_header); + } + for (p = path_list; p; p = p->next) total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + sizeof (struct grub_module_header)); @@ -848,10 +813,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size, &start_address, &rel_section, &reloc_size, &align, image_target); - if (image_target->prefix + strlen (prefix) + 1 > image_target->prefix_end) - grub_util_error (_("prefix is too long")); - strcpy (kernel_img + image_target->prefix, prefix); - if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) && (image_target->total_module_size != TARGET_NO_FIELD)) *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) @@ -943,6 +904,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += config_size; } + if (prefix) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX); + header->size = grub_host_to_target32 (prefix_size + sizeof (*header)); + offset += sizeof (*header); + + grub_memset (kernel_img + offset, 0, prefix_size); + grub_strcpy (kernel_img + offset, prefix); + offset += prefix_size; + } + grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size, comp); From 544c24876e2f20e217c615e10cb802aa1d8295be Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 16:53:18 +0200 Subject: [PATCH 066/315] Move grub_reboot out of the kernel. * grub-core/Makefile.core.def (reboot): Add platform-specific files. * grub-core/kern/efi/efi.c (grub_reboot): Moved to ... * grub-core/lib/efi/reboot.c: ... here. * grub-core/kern/i386/efi/startup.S: Remove including of realmode.S. * grub-core/kern/i386/ieee1275/startup.S: Likewise. * grub-core/kern/i386/pc/startup.S (grub_exit): Inline cold_reboot. * grub-core/kern/i386/realmode.S (grub_reboot): Moved to... * grub-core/lib/i386/reboot_trampoline.S: ... here. * grub-core/kern/ieee1275/openfw.c (grub_reboot): Moved to... * grub-core/lib/ieee1275/reboot.c: ... here. * grub-core/kern/mips/arc/init.c (grub_reboot): Moved to... * grub-core/lib/mips/arc/reboot.c: ... here. * grub-core/kern/mips/loongson/init.c (grub_reboot): Moved to... * grub-core/lib/mips/loongson/reboot.c: ...here. * grub-core/kern/mips/qemu_mips/init.c (grub_reboot): Moved to... * grub-core/lib/mips/qemu_mips/reboot.c: ... here. * include/grub/emu/misc.h (grub_reboot): New function declaration. * include/grub/i386/reboot.h: New file. * include/grub/mips/loongson/ec.h: Fix includes. * include/grub/mips/qemu_mips/kernel.h (grub_reboot): Removed. * include/grub/misc.h (grub_reboot): Don't mark as kernel function. * grub-core/lib/i386/reboot.c: New file. --- ChangeLog | 27 ++++++++++++ grub-core/Makefile.core.def | 19 ++++++--- grub-core/kern/efi/efi.c | 12 ------ grub-core/kern/i386/efi/startup.S | 2 - grub-core/kern/i386/ieee1275/startup.S | 6 --- grub-core/kern/i386/pc/startup.S | 5 ++- grub-core/kern/i386/realmode.S | 15 ------- grub-core/kern/ieee1275/openfw.c | 10 ----- grub-core/kern/mips/arc/init.c | 12 ------ grub-core/kern/mips/loongson/init.c | 32 -------------- grub-core/kern/mips/qemu_mips/init.c | 6 --- grub-core/lib/efi/reboot.c | 32 ++++++++++++++ grub-core/lib/i386/reboot.c | 59 ++++++++++++++++++++++++++ grub-core/lib/i386/reboot_trampoline.S | 33 ++++++++++++++ grub-core/lib/ieee1275/reboot.c | 27 ++++++++++++ grub-core/lib/mips/arc/reboot.c | 34 +++++++++++++++ grub-core/lib/mips/loongson/reboot.c | 57 +++++++++++++++++++++++++ grub-core/lib/mips/qemu_mips/reboot.c | 25 +++++++++++ include/grub/emu/misc.h | 3 ++ include/grub/i386/reboot.h | 28 ++++++++++++ include/grub/mips/loongson/ec.h | 4 ++ include/grub/mips/qemu_mips/kernel.h | 1 - include/grub/misc.h | 2 +- 23 files changed, 348 insertions(+), 103 deletions(-) create mode 100644 grub-core/lib/efi/reboot.c create mode 100644 grub-core/lib/i386/reboot.c create mode 100644 grub-core/lib/i386/reboot_trampoline.S create mode 100644 grub-core/lib/ieee1275/reboot.c create mode 100644 grub-core/lib/mips/arc/reboot.c create mode 100644 grub-core/lib/mips/loongson/reboot.c create mode 100644 grub-core/lib/mips/qemu_mips/reboot.c create mode 100644 include/grub/i386/reboot.h diff --git a/ChangeLog b/ChangeLog index a758fc275..9bea2dc0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2011-10-19 Vladimir Serbinenko + + Move grub_reboot out of the kernel. + + * grub-core/Makefile.core.def (reboot): Add platform-specific files. + * grub-core/kern/efi/efi.c (grub_reboot): Moved to ... + * grub-core/lib/efi/reboot.c: ... here. + * grub-core/kern/i386/efi/startup.S: Remove including of realmode.S. + * grub-core/kern/i386/ieee1275/startup.S: Likewise. + * grub-core/kern/i386/pc/startup.S (grub_exit): Inline cold_reboot. + * grub-core/kern/i386/realmode.S (grub_reboot): Moved to... + * grub-core/lib/i386/reboot_trampoline.S: ... here. + * grub-core/kern/ieee1275/openfw.c (grub_reboot): Moved to... + * grub-core/lib/ieee1275/reboot.c: ... here. + * grub-core/kern/mips/arc/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/arc/reboot.c: ... here. + * grub-core/kern/mips/loongson/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/loongson/reboot.c: ...here. + * grub-core/kern/mips/qemu_mips/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/qemu_mips/reboot.c: ... here. + * include/grub/emu/misc.h (grub_reboot): New function declaration. + * include/grub/i386/reboot.h: New file. + * include/grub/mips/loongson/ec.h: Fix includes. + * include/grub/mips/qemu_mips/kernel.h (grub_reboot): Removed. + * include/grub/misc.h (grub_reboot): Don't mark as kernel function. + * grub-core/lib/i386/reboot.c: New file. + 2011-10-18 Vladimir Serbinenko Make grub_prefix into module to fix the arbitrary limit and save diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 84739e8fa..396f73b44 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -633,6 +633,20 @@ module = { emu = lib/emu/halt.c; }; +module = { + name = reboot; + i386 = lib/i386/reboot.c; + i386 = lib/i386/reboot_trampoline.S; + ia64_efi = lib/efi/reboot.c; + x86_64_efi = lib/efi/reboot.c; + powerpc_ieee1275 = lib/ieee1275/reboot.c; + sparc64_ieee1275 = lib/ieee1275/reboot.c; + mips_arc = lib/mips/arc/reboot.c; + mips_loongson = lib/mips/loongson/reboot.c; + mips_qemu_mips = lib/mips/qemu_mips/reboot.c; + common = commands/reboot.c; +}; + module = { name = hashsum; common = commands/hashsum.c; @@ -733,11 +747,6 @@ module = { common = commands/read.c; }; -module = { - name = reboot; - common = commands/reboot.c; -}; - module = { name = search; common = commands/search_wrap.c; diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index e27dd1ad0..9a2c5e64d 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -163,18 +163,6 @@ grub_exit (void) for (;;) ; } -/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ -#ifndef __i386__ -void -grub_reboot (void) -{ - grub_efi_fini (); - efi_call_4 (grub_efi_system_table->runtime_services->reset_system, - GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); - for (;;) ; -} -#endif - grub_err_t grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, grub_efi_uintn_t descriptor_size, diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 49b05c1e6..0f904d7b3 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -51,5 +51,3 @@ codestart: movl %eax, EXT_C(grub_efi_system_table) call EXT_C(grub_main) ret - -#include "../realmode.S" diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 6b39f5f3a..245583bdb 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -39,9 +39,3 @@ _start: movl %eax, EXT_C(grub_ieee1275_entry_fn) jmp EXT_C(grub_main) -/* - * prot_to_real and associated structures (but NOT real_to_prot, that is - * only needed for BIOS gates). - */ -#include "../realmode.S" - diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 3bbe34753..a70a2a7db 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -465,7 +465,10 @@ FUNCTION(grub_exit) .code16 /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 - jmp cold_reboot + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 .code32 /* diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 578c8d2a8..3e8a13892 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -225,18 +225,3 @@ realcseg: DATA32 ret .code32 - -/* - * grub_reboot() - * - * Reboot the system. At the moment, rely on BIOS. - */ -FUNCTION(grub_reboot) - call prot_to_real - .code16 -cold_reboot: - /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ - movw $0x0472, %di - movw %ax, (%di) - ljmp $0xf000, $0xfff0 - .code32 diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 4e705a4d8..23065e3e3 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -456,16 +456,6 @@ grub_ieee1275_encode_devname (const char *path) return encoding; } -/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ -#ifndef __i386__ -void -grub_reboot (void) -{ - grub_ieee1275_interpret ("reset-all", 0); - for (;;) ; -} -#endif - /* Resolve aliases. */ char * grub_ieee1275_canonicalise_devname (const char *path) diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 2e25335ca..ec0fa521a 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -195,15 +195,3 @@ grub_exit (void) while (1); } -void -grub_reboot (void) -{ - GRUB_ARC_FIRMWARE_VECTOR->restart (); - - grub_millisleep (1500); - - grub_printf ("Reboot failed\n"); - grub_refresh (); - while (1); -} - diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 8acfb0767..6ddf151f2 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -30,7 +30,6 @@ #include #include #include -#include #include extern void grub_video_sm712_init (void); @@ -266,37 +265,6 @@ grub_exit (void) grub_halt (); } -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_printf ("Reboot failed\n"); - grub_refresh (); - while (1); -} - extern char _end[]; grub_addr_t grub_modbase = (grub_addr_t) _end; diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 4921c42bf..d331e1b24 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -99,12 +99,6 @@ grub_halt (void) while (1); } -void -grub_reboot (void) -{ - while (1); -} - grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook) { diff --git a/grub-core/lib/efi/reboot.c b/grub-core/lib/efi/reboot.c new file mode 100644 index 000000000..9382370f7 --- /dev/null +++ b/grub-core/lib/efi/reboot.c @@ -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 . + */ + +#include +#include +#include +#include +#include + +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 (;;) ; +} diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c new file mode 100644 index 000000000..ef28f7f65 --- /dev/null +++ b/grub-core/lib/i386/reboot.c @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +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; + + grub_stop_floppy (); + + err = grub_relocator16_boot (relocator, state); + + while (1); +} + diff --git a/grub-core/lib/i386/reboot_trampoline.S b/grub-core/lib/i386/reboot_trampoline.S new file mode 100644 index 000000000..18bcfb287 --- /dev/null +++ b/grub-core/lib/i386/reboot_trampoline.S @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + + .p2align 4 + +VARIABLE(grub_reboot_start) + .code16 + + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 + + .code32 +VARIABLE(grub_reboot_end) diff --git a/grub-core/lib/ieee1275/reboot.c b/grub-core/lib/ieee1275/reboot.c new file mode 100644 index 000000000..91c8779f2 --- /dev/null +++ b/grub-core/lib/ieee1275/reboot.c @@ -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 . + */ + +#include +#include + +void +grub_reboot (void) +{ + grub_ieee1275_interpret ("reset-all", 0); + for (;;) ; +} diff --git a/grub-core/lib/mips/arc/reboot.c b/grub-core/lib/mips/arc/reboot.c new file mode 100644 index 000000000..f0d085765 --- /dev/null +++ b/grub-core/lib/mips/arc/reboot.c @@ -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 . + */ + +#include +#include +#include +#include + +void +grub_reboot (void) +{ + GRUB_ARC_FIRMWARE_VECTOR->restart (); + + grub_millisleep (1500); + + grub_printf ("Reboot failed\n"); + grub_refresh (); + while (1); +} diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c new file mode 100644 index 000000000..f099ba250 --- /dev/null +++ b/grub-core/lib/mips/loongson/reboot.c @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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_printf ("Reboot failed\n"); + grub_refresh (); + while (1); +} diff --git a/grub-core/lib/mips/qemu_mips/reboot.c b/grub-core/lib/mips/qemu_mips/reboot.c new file mode 100644 index 000000000..a5c41ee78 --- /dev/null +++ b/grub-core/lib/mips/qemu_mips/reboot.c @@ -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 . + */ + +#include + +void +grub_reboot (void) +{ + while (1); +} diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index fcf9da473..b4b8f7d28 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -82,4 +82,7 @@ int grub_device_mapper_supported (void); char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot); +void EXPORT_FUNC(grub_reboot) (void); + + #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/i386/reboot.h b/include/grub/i386/reboot.h new file mode 100644 index 000000000..c2716f3fa --- /dev/null +++ b/include/grub/i386/reboot.h @@ -0,0 +1,28 @@ +/* + * 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 . + */ + +#ifndef GRUB_REBOOT_H +#define GRUB_REBOOT_H 1 + +#ifndef ASM_FILE + +extern grub_uint8_t grub_reboot_end[], grub_reboot_start[]; + +#endif + +#endif diff --git a/include/grub/mips/loongson/ec.h b/include/grub/mips/loongson/ec.h index 62d1d33d9..3f8ff9931 100644 --- a/include/grub/mips/loongson/ec.h +++ b/include/grub/mips/loongson/ec.h @@ -19,6 +19,10 @@ #ifndef GRUB_EC_MACHINE_HEADER #define GRUB_EC_MACHINE_HEADER 1 +#include +#include +#include + #define GRUB_MACHINE_EC_MAGIC_PORT1 0x381 #define GRUB_MACHINE_EC_MAGIC_PORT2 0x382 #define GRUB_MACHINE_EC_DATA_PORT 0x383 diff --git a/include/grub/mips/qemu_mips/kernel.h b/include/grub/mips/qemu_mips/kernel.h index 66add4b2e..1e7e32401 100644 --- a/include/grub/mips/qemu_mips/kernel.h +++ b/include/grub/mips/qemu_mips/kernel.h @@ -23,7 +23,6 @@ #ifndef ASM_FILE -void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); void grub_qemu_init_cirrus (void); diff --git a/include/grub/misc.h b/include/grub/misc.h index 66e74d8a8..0a0a4135e 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -343,7 +343,7 @@ grub_div_roundup (unsigned int x, unsigned int y) } /* Reboot the machine. */ -void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn)); +void grub_reboot (void) __attribute__ ((noreturn)); #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't From f8f72eb890273c7dc6cae48420d21a3d4e437213 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:28:09 +0200 Subject: [PATCH 067/315] * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Don't add the bogus brackets. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/openfw.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d66419216..ee678a9e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Vladimir Serbinenko + + * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Don't add the bogus brackets. + 2011-10-19 Vladimir Serbinenko ExFAT support. diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 23065e3e3..57252d96b 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -445,10 +445,10 @@ grub_ieee1275_encode_devname (const char *path) /* GRUB partition 1 is OF partition 0. */ partno++; - encoding = grub_xasprintf ("(%s,%d)", device, partno); + encoding = grub_xasprintf ("%s,%d", device, partno); } else - encoding = grub_xasprintf ("(%s)", device); + encoding = grub_strdup (device); grub_free (partition); grub_free (device); From 36dd20ad0bc2bd9b46ce48cc0425512018cac21f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:30:06 +0200 Subject: [PATCH 068/315] * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. --- ChangeLog | 4 ++++ grub-core/kern/main.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee678a9e3..6210a4eab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-19 Vladimir Serbinenko + + * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. + 2011-10-19 Vladimir Serbinenko * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 77be11422..bf2789860 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -105,7 +105,7 @@ grub_set_prefix_and_root (void) char *path = NULL; char *fwdevice = NULL; char *fwpath = NULL; - char *prefix; + char *prefix = NULL; struct grub_module_header *header; FOR_MODULES (header) From e55599dcbf2f4773674995703cbf1a71cba3e355 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:35:41 +0200 Subject: [PATCH 069/315] * util/grub-install.in: Declare IEEE1275 as able to find out the disk name. --- ChangeLog | 5 +++++ util/grub-install.in | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6210a4eab..afbc8aec7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Vladimir Serbinenko + + * util/grub-install.in: Declare IEEE1275 as able to find out the disk + name. + 2011-10-19 Vladimir Serbinenko * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. diff --git a/util/grub-install.in b/util/grub-install.in index d11d24421..e1255f4f7 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -544,11 +544,11 @@ if [ "x${devabstraction_module}" = "x" ] ; then # Strip partition number grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`" grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`" - if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]); then + if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then # generic method (used on coreboot and ata mod) uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" if [ "x${uuid}" = "x" ] ; then - if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]; then + if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 elif [ "$disk_module" = ata ]; then echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 @@ -563,7 +563,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" - elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then + elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ] || [ "x$platform" = xieee1275 ]; then # we need to hardcode the partition number in the core image's prefix. if [ x"$grub_partition" = x ]; then prefix_drive="()" From de9c615e5c5b9d692ac00be91b16a0576a371e25 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 23:01:44 +0200 Subject: [PATCH 070/315] Removed unused GRUB_BOOT_VERSION. Check for kernel version is better done with a dedicated section. * grub-core/boot/sparc64/ieee1275/boot.S: Remove GRUB_BOOT_VERSION. Ensure the correct position of boot_path. * grub-core/kern/i386/efi/startup.S: Remove GRUB_BOOT_VERSION. * grub-core/kern/i386/pc/startup.S: Likewise. Ensure correct position of other fields. * grub-core/kern/x86_64/efi/startup.S: Remove GRUB_BOOT_VERSION. * include/grub/boot.h: Removed. All references removed. * include/grub/sparc64/ieee1275/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): Removed. (GRUB_BOOT_MACHINE_BOOT_DEVPATH): Make it lower. --- ChangeLog | 16 +++++++++++++ grub-core/Makefile.am | 1 - grub-core/boot/i386/pc/boot.S | 1 - grub-core/boot/i386/pc/cdboot.S | 1 - grub-core/boot/i386/pc/lnxboot.S | 1 - grub-core/boot/sparc64/ieee1275/boot.S | 5 +--- grub-core/boot/sparc64/ieee1275/diskboot.S | 1 - grub-core/kern/i386/efi/startup.S | 17 -------------- grub-core/kern/i386/pc/startup.S | 19 ++++++--------- grub-core/kern/x86_64/efi/callwrap.S | 1 - grub-core/kern/x86_64/efi/startup.S | 13 ----------- include/grub/boot.h | 27 ---------------------- include/grub/sparc64/ieee1275/boot.h | 4 +--- 13 files changed, 25 insertions(+), 82 deletions(-) delete mode 100644 include/grub/boot.h diff --git a/ChangeLog b/ChangeLog index afbc8aec7..1159d32a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-10-19 Vladimir Serbinenko + + Removed unused GRUB_BOOT_VERSION. Check for kernel version is better + done with a dedicated section. + + * grub-core/boot/sparc64/ieee1275/boot.S: Remove GRUB_BOOT_VERSION. + Ensure the correct position of boot_path. + * grub-core/kern/i386/efi/startup.S: Remove GRUB_BOOT_VERSION. + * grub-core/kern/i386/pc/startup.S: Likewise. Ensure correct position of + other fields. + * grub-core/kern/x86_64/efi/startup.S: Remove GRUB_BOOT_VERSION. + * include/grub/boot.h: Removed. All references removed. + * include/grub/sparc64/ieee1275/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): + Removed. + (GRUB_BOOT_MACHINE_BOOT_DEVPATH): Make it lower. + 2011-10-19 Vladimir Serbinenko * util/grub-install.in: Declare IEEE1275 as able to find out the disk diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index f30014635..3bd192602 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -78,7 +78,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 635599a24..314f14016 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -18,7 +18,6 @@ */ #include -#include #include /* diff --git a/grub-core/boot/i386/pc/cdboot.S b/grub-core/boot/i386/pc/cdboot.S index 33569ce9d..d939835a9 100644 --- a/grub-core/boot/i386/pc/cdboot.S +++ b/grub-core/boot/i386/pc/cdboot.S @@ -18,7 +18,6 @@ */ #include -#include #include #include #include diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index 2c7596026..bb43ed73c 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S index f08258f47..f79699502 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/grub-core/boot/sparc64/ieee1275/boot.S @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include .text @@ -29,9 +28,6 @@ pic_base: call boot_continue mov %o4, CIF_REG - . = _start + GRUB_BOOT_MACHINE_VER_MAJ -boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - /* The offsets to these locations are defined by the * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h, * and grub-setup uses this to patch these next three values as needed. @@ -44,6 +40,7 @@ boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR * After loading in that block we will execute it by jumping to the * load address plus the size of the prepended A.OUT header (32 bytes). */ + . = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH boot_path: . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE boot_path_end: diff --git a/grub-core/boot/sparc64/ieee1275/diskboot.S b/grub-core/boot/sparc64/ieee1275/diskboot.S index 83dfee098..e020f6221 100644 --- a/grub-core/boot/sparc64/ieee1275/diskboot.S +++ b/grub-core/boot/sparc64/ieee1275/diskboot.S @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include #include diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 0f904d7b3..fc5ea3dac 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -19,29 +19,12 @@ #include #include -#include .file "startup.S" .text .globl start, _start start: _start: - jmp codestart - - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - - /* - * This is a special data area 8 bytes from the beginning. - */ - -codestart: /* * EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack. */ diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a70a2a7db..0350431d9 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -75,31 +74,27 @@ LOCAL (base): #else ljmp $0, $ABS(LOCAL (codestart)) #endif - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR /* - * This is a special data area 8 bytes from the beginning. + * This is a special data area. */ - . = _start + 0x8 - + . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE VARIABLE(grub_total_module_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE VARIABLE(grub_kernel_image_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE VARIABLE(grub_compressed_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART VARIABLE(grub_install_dos_part) .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY reed_solomon_redundancy: .long 0 diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index cc2c8aa05..dced859ac 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -19,7 +19,6 @@ #include #include -#include /* * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index 37efde7fc..f86f01969 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -19,7 +19,6 @@ #include #include -#include .file "startup.S" .text @@ -28,18 +27,6 @@ start: _start: - jmp codestart - - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - -codestart: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) diff --git a/include/grub/boot.h b/include/grub/boot.h deleted file mode 100644 index 235774863..000000000 --- a/include/grub/boot.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_BOOT_HEADER -#define GRUB_BOOT_HEADER 1 - -#define GRUB_BOOT_VERSION_MAJOR 4 -#define GRUB_BOOT_VERSION_MINOR 0 -#define GRUB_BOOT_VERSION ((GRUB_BOOT_VERSION_MINOR << 8) \ - | GRUB_BOOT_VERSION_MAJOR) - -#endif /* ! GRUB_BOOT_HEADER */ diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 112d19bc7..60edc712e 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -39,9 +39,7 @@ #define GRUB_BOOT_MACHINE_SIGNATURE 0xbb44aa55 -#define GRUB_BOOT_MACHINE_VER_MAJ 0x08 - -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x08 #define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 From fcf1d67219695832a42525d3f9c9dc0730e72bf5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 19 Oct 2011 23:11:48 +0200 Subject: [PATCH 071/315] * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible NULL pointer dereference. --- ChangeLog | 5 +++++ grub-core/bus/usb/uhci.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1159d32a5..96abe1229 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Szymon Janc + + * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible + NULL pointer dereference. + 2011-10-19 Vladimir Serbinenko Removed unused GRUB_BOOT_VERSION. Check for kernel version is better diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 260b7e876..a9a4c45a2 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -544,8 +544,11 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, { grub_size_t actual = 0; /* Terminate and free. */ - td_prev->linkptr2 = 0; - td_prev->linkptr = 1; + if (td_prev) + { + td_prev->linkptr2 = 0; + td_prev->linkptr = 1; + } if (cdata->td_first) grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual); From 766f7d08092a0904cb00af1b419fb8b8edcdb51b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 20 Oct 2011 08:13:00 +0200 Subject: [PATCH 072/315] Remove redundant grub_kernel_image_size. * grub-core/kern/i386/coreboot/init.c (grub_machine_init): Use _edata and _start. * grub-core/kern/i386/coreboot/startup.S: Move multiboot header after the small code. It moves it only by few bytes but simplifies the code. * grub-core/kern/i386/pc/init.c (grub_machine_init): Use _edata and _start. * grub-core/kern/i386/pc/startup.S: Use _edata and _start. (grub_kernel_image_size): Removed. * grub-core/kern/i386/qemu/startup.S: Use _edata and _start. (grub_kernel_image_size): Removed. [APPLE_CC]: Remove apple compiler support. i386-qemu port can't be compiled with Apple toolchain. * grub-core/kern/sparc64/ieee1275/crt0.S: Remove leftover fields. * include/grub/i386/pc/kernel.h (grub_kernel_image_size): Removed. * include/grub/i386/qemu/kernel.h (grub_kernel_image_size): Removed. (grub_total_module_size): Likewise. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE): Removed. (GRUB_KERNEL_I386_PC_COMPRESSED_SIZE): Put it lower. (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Likewise. (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Likewise. (GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE): Removed. (GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE): Likewise. * include/grub/sparc64/ieee1275/kernel.h (grub_kernel_image_size): Removed. (grub_total_module_size): Removed. * util/grub-mkimage.c (image_target_desc): Remove image_size. (image_targets): Likewise. Set .compressed_size to no field on sparc. (generate_image): Remove kernel_image_size handling. --- ChangeLog | 37 ++++++++++++++++++++++++++ grub-core/kern/i386/coreboot/init.c | 7 ++--- grub-core/kern/i386/coreboot/startup.S | 27 +++++++++---------- grub-core/kern/i386/pc/init.c | 3 ++- grub-core/kern/i386/pc/startup.S | 5 +--- grub-core/kern/i386/qemu/startup.S | 20 +------------- grub-core/kern/sparc64/ieee1275/crt0.S | 4 --- include/grub/i386/pc/kernel.h | 3 --- include/grub/i386/qemu/kernel.h | 6 ----- include/grub/offsets.h | 20 +++----------- include/grub/sparc64/ieee1275/kernel.h | 6 ----- util/grub-mkimage.c | 28 ++----------------- 12 files changed, 63 insertions(+), 103 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96abe1229..bf96dc095 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2011-10-20 Vladimir Serbinenko + + Remove redundant grub_kernel_image_size. + + * grub-core/kern/i386/coreboot/init.c (grub_machine_init): Use + _edata and _start. + * grub-core/kern/i386/coreboot/startup.S: Move multiboot header after + the small code. It moves it only by few bytes but simplifies the code. + * grub-core/kern/i386/pc/init.c (grub_machine_init): Use _edata and + _start. + * grub-core/kern/i386/pc/startup.S: Use _edata and _start. + (grub_kernel_image_size): Removed. + * grub-core/kern/i386/qemu/startup.S: Use _edata and _start. + (grub_kernel_image_size): Removed. + [APPLE_CC]: Remove apple compiler support. i386-qemu port can't be + compiled with Apple toolchain. + * grub-core/kern/sparc64/ieee1275/crt0.S: Remove leftover fields. + * include/grub/i386/pc/kernel.h (grub_kernel_image_size): Removed. + * include/grub/i386/qemu/kernel.h (grub_kernel_image_size): Removed. + (grub_total_module_size): Likewise. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE): + Removed. + (GRUB_KERNEL_I386_PC_COMPRESSED_SIZE): Put it lower. + (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Likewise. + (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. + (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Likewise. + (GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE): Removed. + (GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE): Likewise. + * include/grub/sparc64/ieee1275/kernel.h (grub_kernel_image_size): + Removed. + (grub_total_module_size): Removed. + * util/grub-mkimage.c (image_target_desc): Remove image_size. + (image_targets): Likewise. + Set .compressed_size to no field on sparc. + (generate_image): Remove kernel_image_size handling. + 2011-10-19 Szymon Janc * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index b7510ff98..95209bb70 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -38,8 +38,9 @@ #include #endif -extern char _start[]; -extern char _end[]; +extern grub_uint8_t _start[]; +extern grub_uint8_t _end[]; +extern grub_uint8_t _edata[]; grub_uint32_t grub_get_rtc (void) @@ -66,7 +67,7 @@ void grub_machine_init (void) { #ifdef GRUB_MACHINE_QEMU - grub_modbase = grub_core_entry_addr + grub_kernel_image_size; + grub_modbase = grub_core_entry_addr + (_edata - _start); grub_qemu_init_cirrus (); #endif diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index 5e7767bb9..dc2c62a25 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -38,21 +38,6 @@ .globl start, _start start: _start: - jmp codestart - -/* - * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). - */ - .p2align 2 /* force 4-byte alignment */ -multiboot_header: - /* magic */ - .long 0x1BADB002 - /* flags */ - .long MULTIBOOT_MEMORY_INFO - /* checksum */ - .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO - -codestart: #ifdef GRUB_MACHINE_MULTIBOOT cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax jne 0f @@ -66,6 +51,18 @@ codestart: /* jump to the main body of C code */ jmp EXT_C(grub_main) +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long MULTIBOOT_MEMORY_INFO + /* checksum */ + .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO + /* * prot_to_real and associated structures (but NOT real_to_prot, that is * only needed for BIOS gates). diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 62269de78..be26fdea1 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -130,6 +130,7 @@ compact_mem_regions (void) } grub_addr_t grub_modbase; +extern grub_uint8_t _start[], _edata[]; void grub_machine_init (void) @@ -140,7 +141,7 @@ grub_machine_init (void) #endif grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + + ((_edata - _start) - GRUB_KERNEL_MACHINE_RAW_SIZE); /* Initialize the console as early as possible. */ grub_console_init (); diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 0350431d9..a0ef71f90 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -81,9 +81,6 @@ LOCAL (base): . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE VARIABLE(grub_total_module_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE -VARIABLE(grub_kernel_image_size) .long 0 . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE VARIABLE(grub_compressed_size) @@ -226,7 +223,7 @@ post_reed_solomon: movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi pushl %edi pushl %esi - movl EXT_C(grub_kernel_image_size), %ecx + movl $(BSS_START_SYMBOL - _start), %ecx addl EXT_C(grub_total_module_size), %ecx subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx pushl %ecx diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 6500de620..0761807ed 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -32,8 +32,6 @@ _start: . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 -VARIABLE(grub_kernel_image_size) - .long 0 codestart: /* Relocate to low memory. First we figure out our location. @@ -45,11 +43,7 @@ codestart: value of `grub_core_entry_addr' in %esi. */ xorw %si, %si - /* ... which allows us to access `grub_kernel_image_size' - before relocation. */ - movl (grub_kernel_image_size - _start)(%esi), %ecx - - + movl $(_edata - _start), %ecx movl $_start, %edi cld rep @@ -57,24 +51,12 @@ codestart: ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f 1: -#ifdef APPLE_CC - /* clean out the bss */ - bss_start_abs = ABS (bss_start) - bss_end_abs = ABS (bss_end) - - movl bss_start_abs, %edi - - /* compute the bss length */ - movl bss_end_abs, %ecx - subl %edi, %ecx -#else /* clean out the bss */ movl $BSS_START_SYMBOL, %edi /* compute the bss length */ movl $END_SYMBOL, %ecx subl %edi, %ecx -#endif /* clean out */ xorl %eax, %eax diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index 1466a56f8..9d91fba48 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -31,10 +31,6 @@ _start: VARIABLE(grub_total_module_size) .word 0 -VARIABLE(grub_kernel_image_size) - .word 0 -VARIABLE(grub_compressed_size) - .word 0 codestart: /* Copy the modules past the end of the kernel image. diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index dd50aa833..2dcdbb7a6 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -29,9 +29,6 @@ #include #include -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index df06e6731..f34206b3a 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -28,12 +28,6 @@ extern grub_addr_t grub_core_entry_addr; -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - -/* The total size of module images following the kernel. */ -extern grub_int32_t grub_total_module_size; - void grub_qemu_init_cirrus (void); #endif /* ! ASM_FILE */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 526cfee68..aa65cd5cc 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -22,20 +22,17 @@ /* The offset of GRUB_TOTAL_MODULE_SIZE. */ #define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc - /* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x0c /* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 /* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x14 /* Offset of reed_solomon_redundancy. */ -#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x1c +#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 /* The size of the first region which won't be compressed. */ #define GRUB_KERNEL_I386_PC_RAW_SIZE 0xcd0 @@ -57,20 +54,11 @@ /* The offset of GRUB_CORE_ENTRY_ADDR. */ #define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc - #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 /* The offset of GRUB_TOTAL_MODULE_SIZE. */ #define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 - #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 5aa50b852..9a00bea61 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -26,12 +26,6 @@ #include #include -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - -/* The total size of module images following the kernel. */ -extern grub_int32_t grub_total_module_size; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4440fdd12..fb1c5babe 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -79,7 +79,6 @@ struct image_target_desc } flags; unsigned raw_size; unsigned total_module_size; - unsigned kernel_image_size; unsigned compressed_size; unsigned link_align; grub_uint16_t elf_target; @@ -110,7 +109,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -131,7 +129,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -152,7 +149,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_LZMA, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, .section_align = 1, .vaddr_offset = 0, @@ -169,7 +165,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_LZMA, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, .section_align = 1, .vaddr_offset = 0, @@ -186,7 +181,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE @@ -209,7 +203,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -231,7 +224,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -247,7 +239,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, @@ -266,7 +257,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -286,7 +276,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -308,7 +297,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -327,7 +315,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -348,8 +335,7 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, - .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -365,8 +351,7 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, - .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -382,7 +367,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, @@ -402,7 +386,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -422,7 +405,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -442,7 +424,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -462,7 +443,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -482,7 +462,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -935,9 +914,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], && image_target->total_module_size != TARGET_NO_FIELD) *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) = grub_host_to_target32 (total_module_size); - if (image_target->kernel_image_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (kernel_img + image_target->kernel_image_size)) - = grub_host_to_target32 (kernel_size); if (image_target->compressed_size != TARGET_NO_FIELD) *((grub_uint32_t *) (kernel_img + image_target->compressed_size)) = grub_host_to_target32 (core_size - image_target->raw_size); From db1326f5fbdbe15651dafb5ee628118018f1d53c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 Oct 2011 00:16:59 +0200 Subject: [PATCH 073/315] Move chainloader_real_boot out of the kernel --- grub-core/Makefile.am | 1 - grub-core/kern/i386/pc/startup.S | 25 -------- grub-core/lib/i386/reboot.c | 1 + grub-core/lib/i386/relocator.c | 9 ++- grub-core/lib/i386/relocator16.S | 85 ++++++++++++++++++++++++++ grub-core/loader/i386/pc/chainloader.c | 59 ++++++++++++++---- grub-core/loader/i386/pc/freedos.c | 3 +- grub-core/loader/i386/pc/linux.c | 2 +- grub-core/loader/i386/pc/ntldr.c | 3 +- include/grub/i386/pc/loader.h | 27 -------- include/grub/i386/relocator.h | 2 + 11 files changed, 148 insertions(+), 69 deletions(-) delete mode 100644 include/grub/i386/pc/loader.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 3bd192602..4a46e1d9c 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -83,7 +83,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h if COND_i386_pc -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a0ef71f90..e75f3ab90 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -463,31 +463,6 @@ FUNCTION(grub_exit) ljmp $0xf000, $0xfff0 .code32 -/* - * void grub_chainloader_real_boot (int drive, void *part_addr) - * - * This starts another boot loader. - */ - -FUNCTION(grub_chainloader_real_boot) - pushl %edx - pushl %eax - - /* Turn off Gate A20 */ - xorl %eax, %eax - call grub_gate_a20 - - /* set up to pass boot drive */ - popl %edx - - /* ESI must point to a partition table entry */ - popl %esi - - call prot_to_real - .code16 - ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR - .code32 - /* * void grub_console_putchar (int c) * diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c index ef28f7f65..45a2259cf 100644 --- a/grub-core/lib/i386/reboot.c +++ b/grub-core/lib/i386/reboot.c @@ -49,6 +49,7 @@ grub_reboot (void) state.sp = 0; state.cs = segment; state.ip = 0; + state.a20 = 0; grub_stop_floppy (); diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 2f10feb5e..1f0aa0dd1 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -51,6 +51,9 @@ 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; @@ -195,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); @@ -215,6 +219,9 @@ grub_relocator16_boot (struct grub_relocator *rel, 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)); diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index d6673fade..babe69e1d 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -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 */ @@ -132,6 +211,12 @@ VARIABLE(grub_relocator16_sp) .word 0 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) diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index 8d6ec8f20..929569921 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -39,12 +38,14 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; static int boot_drive; -static void *boot_part_addr; +static grub_addr_t boot_part_addr; +static struct grub_relocator *rel; typedef enum { @@ -55,16 +56,29 @@ typedef enum static grub_err_t grub_chainloader_boot (void) { + struct grub_relocator16_state state = { + .edx = boot_drive, + .esi = boot_part_addr, + .ds = 0, + .es = 0, + .fs = 0, + .gs = 0, + .ss = 0, + .cs = 0, + .sp = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, + .ip = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, + .a20 = 0 + }; grub_video_set_mode ("text", 0, 0); - grub_chainloader_real_boot (boot_drive, boot_part_addr); - /* Never reach here. */ - return GRUB_ERR_NONE; + return grub_relocator16_boot (rel, state); } static grub_err_t grub_chainloader_unload (void) { + grub_relocator_unload (rel); + rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; } @@ -133,7 +147,12 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) grub_uint16_t signature; grub_device_t dev; int drive = -1; - void *part_addr = 0; + grub_addr_t part_addr = 0; + grub_uint8_t *bs, *ptable; + + rel = grub_relocator_new (); + if (!rel) + goto fail; grub_dl_ref (my_mod); @@ -142,8 +161,25 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (! file) goto fail; + { + grub_relocator_chunk_t ch; + grub_err_t err; + + err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00, + GRUB_DISK_SECTOR_SIZE); + if (err) + goto fail; + bs = get_virtual_current_address (ch); + err = grub_relocator_alloc_chunk_addr (rel, &ch, + GRUB_MEMORY_MACHINE_PART_TABLE_ADDR, + 64); + if (err) + goto fail; + ptable = get_virtual_current_address (ch); + } + /* Read the first block. */ - if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE) + if (grub_file_read (file, bs, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) { if (grub_errno == GRUB_ERR_NONE) @@ -153,7 +189,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) } /* Check the signature. */ - signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); + signature = *((grub_uint16_t *) (bs + GRUB_DISK_SECTOR_SIZE - 2)); if (signature != grub_le_to_cpu16 (0xaa55) && ! (flags & GRUB_CHAINLOADER_FORCE)) { @@ -177,10 +213,9 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (p && grub_strcmp (p->partmap->name, "msdos") == 0) { disk->partition = p->parent; - grub_disk_read (disk, p->offset, 446, 64, - (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); - part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR - + (p->index << 4)); + grub_disk_read (disk, p->offset, 446, 64, ptable); + part_addr = (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + + (p->index << 4)); disk->partition = p; } } diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c index f796e08f4..1f088e2b5 100644 --- a/grub-core/loader/i386/pc/freedos.c +++ b/grub-core/loader/i386/pc/freedos.c @@ -56,7 +56,8 @@ grub_freedos_boot (void) .ss = GRUB_FREEDOS_STACK_SEGMENT, .sp = GRUB_FREEDOS_STACK_POINTER, .ebx = ebx, - .edx = 0 + .edx = 0, + .a20 = 1 }; grub_video_set_mode ("text", 0, 0); diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index adc6e8b99..c7c099174 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -61,6 +60,7 @@ grub_linux16_boot (void) state.sp = GRUB_LINUX_SETUP_STACK; state.cs = segment + 0x20; state.ip = 0; + state.a20 = 1; grub_video_set_mode ("text", 0, 0); diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c index b2909c191..153b605ed 100644 --- a/grub-core/loader/i386/pc/ntldr.c +++ b/grub-core/loader/i386/pc/ntldr.c @@ -54,7 +54,8 @@ grub_ntldr_boot (void) .gs = 0, .ss = 0, .sp = 0x7c00, - .edx = edx + .edx = edx, + .a20 = 1 }; grub_video_set_mode ("text", 0, 0); diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h deleted file mode 100644 index bfbcaac5a..000000000 --- a/include/grub/i386/pc/loader.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_LOADER_MACHINE_HEADER -#define GRUB_LOADER_MACHINE_HEADER 1 - -#include - -/* This is an asm part of the chainloader. */ -void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn)); - -#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h index 778049eef..b2fe900b6 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -48,6 +48,8 @@ struct grub_relocator16_state grub_uint16_t ip; grub_uint32_t ebx; grub_uint32_t edx; + grub_uint32_t esi; + int a20; }; struct grub_relocator64_state From 7bec1053db4da195301d418bd82dd5316b28002e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:40:26 +0200 Subject: [PATCH 074/315] * util/grub.d/10_hurd.in: Add datarootdir as per automake manual suggestion. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/10_netbsd.in: Likewise. * util/grub.d/10_windows.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 10 ++++++++++ util/grub.d/10_hurd.in | 1 + util/grub.d/10_kfreebsd.in | 1 + util/grub.d/10_linux.in | 1 + util/grub.d/10_netbsd.in | 1 + util/grub.d/10_windows.in | 1 + util/grub.d/20_linux_xen.in | 1 + 7 files changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index bf96dc095..0b179811c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-20 Vladimir Serbinenko + + * util/grub.d/10_hurd.in: Add datarootdir as per automake manual + suggestion. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-10-20 Vladimir Serbinenko Remove redundant grub_kernel_image_size. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 9ca01f0a8..d04b0a4fe 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -20,6 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib CLASS="--class gnu --class os" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index e4bfc06cb..e668f3fd9 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 97e7c6523..c3565096b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index c257aeb3c..8c232b01b 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 941267a9f..0a848880d 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -20,6 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib case "`uname 2>/dev/null`" in diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index c0b255598..2f1b4af88 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ From 7a5c54a437d148d3f8de45b3adaa9a77d6e5de44 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:53:21 +0200 Subject: [PATCH 075/315] * util/grub-install.in: Add datarootdir as per automake manual suggestion. * util/grub-mknetdir.in: Likewise. --- ChangeLog | 8 +++++++- util/grub-install.in | 1 + util/grub-mknetdir.in | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0b179811c..17db9da19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ -2011-10-20 Vladimir Serbinenko +2011-10-23 Vladimir Serbinenko + + * util/grub-install.in: Add datarootdir as per automake manual + suggestion. + * util/grub-mknetdir.in: Likewise. + +2011-10-23 Vladimir Serbinenko * util/grub.d/10_hurd.in: Add datarootdir as per automake manual suggestion. diff --git a/util/grub-install.in b/util/grub-install.in index e1255f4f7..fdbe10e76 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -31,6 +31,7 @@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ host_os=@host_os@ +datarootdir=@datarootdir@ pkglibdir="${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`" localedir="@datadir@/locale" diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index 52598a8c9..e5a2172fd 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -29,6 +29,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ host_os=@host_os@ localedir=@datadir@/locale +datarootdir=@datarootdir@ pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" self=`basename $0` From d1e293bbfac2f1890d6d8ab4fbc72adb43536adf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:55:32 +0200 Subject: [PATCH 076/315] * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of grub_memcmp usage. --- ChangeLog | 5 +++++ grub-core/io/lzopio.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 17db9da19..5899c1e95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of + grub_memcmp usage. + 2011-10-23 Vladimir Serbinenko * util/grub-install.in: Add datarootdir as per automake manual diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 02a70f4d8..bd6f8e738 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -397,7 +397,7 @@ test_header (grub_file_t file) if (hcheck) { checksum = grub_cpu_to_be32(checksum); - if (memcmp(&checksum, hcheck->read(context), sizeof(checksum)) != 0) + if (grub_memcmp (&checksum, hcheck->read(context), sizeof(checksum)) != 0) goto CORRUPTED; } From 3ce69fc90f62b3ca01239bdc826d4960df15ce83 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:04:57 +0200 Subject: [PATCH 077/315] * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. * grub-core/lib/i386/reboot_trampoline.S (grub_reboot_start): Likewise. --- ChangeLog | 6 ++++++ grub-core/kern/i386/pc/startup.S | 1 + grub-core/lib/i386/reboot_trampoline.S | 1 + 3 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5899c1e95..f5b846ddd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. + * grub-core/lib/i386/reboot_trampoline.S (grub_reboot_start): + Likewise. + 2011-10-23 Vladimir Serbinenko * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a0ef71f90..5277695b1 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -458,6 +458,7 @@ FUNCTION(grub_exit) /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + xorw %ax, %ax movw $0x0472, %di movw %ax, (%di) ljmp $0xf000, $0xfff0 diff --git a/grub-core/lib/i386/reboot_trampoline.S b/grub-core/lib/i386/reboot_trampoline.S index 18bcfb287..c088cd081 100644 --- a/grub-core/lib/i386/reboot_trampoline.S +++ b/grub-core/lib/i386/reboot_trampoline.S @@ -26,6 +26,7 @@ VARIABLE(grub_reboot_start) /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ movw $0x0472, %di + xorw %ax, %ax movw %ax, (%di) ljmp $0xf000, $0xfff0 From f8bc22a832e290cd5fa80572e248762f71a7274f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:20:11 +0200 Subject: [PATCH 078/315] * util/ieee1275/grub-ofpathname.c: Add missing include. --- ChangeLog | 4 ++++ util/ieee1275/grub-ofpathname.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index f5b846ddd..39a85696e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/ieee1275/grub-ofpathname.c: Add missing include. + 2011-10-23 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c index a9bc2cfda..ee81457b3 100644 --- a/util/ieee1275/grub-ofpathname.c +++ b/util/ieee1275/grub-ofpathname.c @@ -24,6 +24,8 @@ #include "progname.h" +#include + int main(int argc, char **argv) { char *of_path; From 18c575e5c5c4a1df3aadb602244e31677bb8631d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:22:38 +0200 Subject: [PATCH 079/315] * util/grub-setup.c: Add missing include. --- ChangeLog | 4 ++++ util/grub-setup.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 39a85696e..7eb57b134 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/grub-setup.c: Add missing include. + 2011-10-23 Vladimir Serbinenko * util/ieee1275/grub-ofpathname.c: Add missing include. diff --git a/util/grub-setup.c b/util/grub-setup.c index b3a6c5c76..99de26f76 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -49,6 +49,7 @@ #include "progname.h" #include #include +#include #define _GNU_SOURCE 1 #include From 4e94ae657595a0b13656ebf16e65fbd071783663 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:25:06 +0200 Subject: [PATCH 080/315] * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static inline function rather than a define. --- ChangeLog | 5 +++++ include/grub/misc.h | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7eb57b134..782da923e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-23 Vladimir Serbinenko + + * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static + inline function rather than a define. + 2011-10-23 Vladimir Serbinenko * util/grub-setup.c: Add missing include. diff --git a/include/grub/misc.h b/include/grub/misc.h index 0a0a4135e..5bc159e7d 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -49,14 +49,19 @@ #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } #define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args) -/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ -#define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n)) void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c); char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src); +/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ +static inline void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} + static inline char * grub_strcat (char *dest, const char *src) { From 4defb8d59b16c713460ea0929b4439ace3dc2705 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:28:23 +0200 Subject: [PATCH 081/315] * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: New inline function. * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy) [GRUB_UTIL]: Likewise. (memset) [GRUB_UTIL]: Likewise. (memcmp) [GRUB_UTIL]: Likewise. --- ChangeLog | 9 +++++++++ grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 21 ++++++++++++++++++++- grub-core/lib/posix_wrap/string.h | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 782da923e..579f510b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: + New inline function. + * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy) [GRUB_UTIL]: + Likewise. + (memset) [GRUB_UTIL]: Likewise. + (memcmp) [GRUB_UTIL]: Likewise. + 2011-10-23 Vladimir Serbinenko * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h index 59febaeb5..0141400fc 100644 --- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h @@ -87,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 diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h index 4224836e2..f38c97ba4 100644 --- a/grub-core/lib/posix_wrap/string.h +++ b/grub-core/lib/posix_wrap/string.h @@ -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 From 124df5f6caabf6be40434c75b4c945f908d01904 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:32:06 +0200 Subject: [PATCH 082/315] Fine grainely disable warnings on lexer. Remove Wno-error on it. * grub-core/Makefile.core.def (normal): Remove -Wno-error. * grub-core/script/lexer.c: Declare yytext_ptr to avoid having yylex_strncpy. * grub-core/script/yylex.l: Add fine-grained #pragma. --- ChangeLog | 9 +++++++++ grub-core/Makefile.core.def | 2 +- grub-core/script/lexer.c | 1 + grub-core/script/yylex.l | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 579f510b0..637fa622b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-23 Vladimir Serbinenko + + Fine grainely disable warnings on lexer. Remove Wno-error on it. + + * grub-core/Makefile.core.def (normal): Remove -Wno-error. + * grub-core/script/lexer.c: Declare yytext_ptr to avoid having + yylex_strncpy. + * grub-core/script/yylex.l: Add fine-grained #pragma. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7cb83924c..6d3c31ea6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1395,7 +1395,7 @@ module = { extra_dist = script/yylex.l; extra_dist = script/parser.y; - cflags = '$(CFLAGS_POSIX) -Wno-error'; + cflags = '$(CFLAGS_POSIX)'; cppflags = '$(CPPFLAGS_POSIX)'; }; diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index 98279079f..53697c734 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -24,6 +24,7 @@ #include #include +#define yytext_ptr char * #include "grub_script.tab.h" #include "grub_script.yy.h" diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 7195a880d..012d88dbc 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -24,6 +24,9 @@ #include #include "grub_script.tab.h" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + #define yyfree grub_lexer_yyfree #define yyalloc grub_lexer_yyalloc #define yyrealloc grub_lexer_yyrealloc From 3471ecdfd9c08e59f37f8ec8fd530aef26e9f1e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:34:30 +0200 Subject: [PATCH 083/315] * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. --- ChangeLog | 4 ++++ grub-core/lib/setjmp.S | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 637fa622b..6daca7214 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. + 2011-10-23 Vladimir Serbinenko Fine grainely disable warnings on lexer. Remove Wno-error on it. diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index b04fd7439..fb7f94767 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -10,6 +10,7 @@ #include "./powerpc/setjmp.S" #elif defined(__ia64__) #include "./ia64/setjmp.S" +#include "./ia64/longjmp.S" #else #error "Unknown target cpu type" #endif From e084ba18957266042721af925a58d744daf8b842 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:39:00 +0200 Subject: [PATCH 084/315] * util/import_gcry.py: Accept space between # and include. --- ChangeLog | 4 ++++ util/import_gcry.py | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6daca7214..fc5ab9806 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/import_gcry.py: Accept space between # and include. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. diff --git a/util/import_gcry.py b/util/import_gcry.py index 720f19303..befa5ef5f 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -189,10 +189,9 @@ for cipher_file in cipher_files: continue else: fw.write (holdline) - m = re.match ("#include <.*>", line) + m = re.match ("# *include <(.*)>", line) if not m is None: - chmsg = "Removed including of %s" % \ - m.group () [len ("#include <"):len (m.group ()) - 1] + chmsg = "Removed including of %s" % m.groups ()[0] if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: From 534d769e579ad77100d11a397387ebff68fb90cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:40:53 +0200 Subject: [PATCH 085/315] * util/import_gcry.py: Automatically fix camellia.c and camellia.h. --- ChangeLog | 4 ++++ util/import_gcry.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index fc5ab9806..0198ba4ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/import_gcry.py: Automatically fix camellia.c and camellia.h. + 2011-10-23 Vladimir Serbinenko * util/import_gcry.py: Accept space between # and include. diff --git a/util/import_gcry.py b/util/import_gcry.py index befa5ef5f..7591d8f0e 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -104,6 +104,20 @@ for cipher_file in cipher_files: fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") + if cipher_file == "camellia.c": + fw.write ("#include \"camellia.h\"\n") + if cipher_file == "camellia.h": + fw.write ("#include \n") + fw.write ("void camellia_setup128(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_setup192(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_setup256(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_encrypt128(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_encrypt192(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_encrypt256(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt128(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt192(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt256(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("#define memcpy grub_memcpy\n") # Whole libgcrypt is distributed under GPLv3+ or compatible if isc: fw.write ("GRUB_MOD_LICENSE (\"GPLv3+\");\n") From f646e143090e26fc8087f3395fc2c1e03190c584 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:55:38 +0200 Subject: [PATCH 086/315] * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and save some space. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. --- ChangeLog | 7 +++++++ grub-core/lib/reed_solomon.c | 4 ++-- include/grub/offsets.h | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0198ba4ee..ea8804bd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and + save some space. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. + (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. + 2011-10-23 Vladimir Serbinenko * util/import_gcry.py: Automatically fix camellia.c and camellia.h. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 365b76003..78d249c2f 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -57,13 +57,13 @@ typedef grub_uint16_t gf_double_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e #if defined (STANDALONE) && !defined (TEST) -static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; +static gf_single_t * const gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; #else #if defined (STANDALONE) static char *scratch; #endif -static grub_uint8_t gf_invert[256]; +static gf_single_t gf_invert[256]; #endif #define SECTOR_SIZE 512 diff --git a/include/grub/offsets.h b/include/grub/offsets.h index aa65cd5cc..92354f700 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -35,9 +35,9 @@ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xcd0 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc70 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x730 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 From 89481cabbdbbf8dfd937f06f6195bc4135fb86d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 01:31:06 +0200 Subject: [PATCH 087/315] * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 if no label is found. (grub_fat_iterate_dir): Fix file size type. (grub_fat_iterate_dir): Likewise. --- ChangeLog | 7 +++++++ grub-core/fs/fat.c | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea8804bd1..306358faa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 + if no label is found. + (grub_fat_iterate_dir): Fix file size type. + (grub_fat_iterate_dir): Likewise. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index ae705bcfb..36a43fca0 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -485,7 +485,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, + data->logical_sector_bits + GRUB_DISK_SECTOR_BITS); logical_cluster = offset >> logical_cluster_bits; - offset &= (1 << logical_cluster_bits) - 1; + offset &= (1ULL << logical_cluster_bits) - 1; if (logical_cluster < data->cur_cluster_num) { @@ -631,9 +631,9 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, case 0xc0: node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); node.valid_size - = grub_cpu_to_le32 (sec.type_specific.stream_extension.valid_size); + = grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size); node.file_size - = grub_cpu_to_le32 (sec.type_specific.stream_extension.file_size); + = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size); node.have_stream = 1; break; case 0xc1: @@ -1026,6 +1026,8 @@ grub_fat_label (grub_device_t device, char **label) if (! data) return grub_errno; + *label = NULL; + while (1) { offset += sizeof (dir); From e0864e7ab7b79f2f08ab749e6be84dadfa0119e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 10:45:47 +0200 Subject: [PATCH 088/315] Minix FS fixes. * grub-core/fs/minix.c (GRUB_MINIX_INODE_SIZE): Size is always 32-bit. (grub_minix_inode) [!MODE_MINIX2 && !MODE_MINIX3]: Make size 32-bit. Rename ctime to mtime. All users updated. (grub_minix_get_file_block): Fix types and double indirect computations. --- ChangeLog | 9 +++++++++ grub-core/fs/minix.c | 34 ++++++++++++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 306358faa..9065162fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-24 Vladimir Serbinenko + + Minix FS fixes. + + * grub-core/fs/minix.c (GRUB_MINIX_INODE_SIZE): Size is always 32-bit. + (grub_minix_inode) [!MODE_MINIX2 && !MODE_MINIX3]: Make size 32-bit. + Rename ctime to mtime. All users updated. + (grub_minix_get_file_block): Fix types and double indirect computations. + 2011-10-23 Vladimir Serbinenko * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 055f89095..1db2883cd 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -63,7 +63,7 @@ typedef grub_uint16_t grub_minix_ino_t; #define grub_minix_le_to_cpu_ino grub_le_to_cpu16 #endif -#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size)) +#define GRUB_MINIX_INODE_SIZE(data) (grub_le_to_cpu32 (data->inode.size)) #define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode)) #define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \ (data->inode.dir_zones[blk])) @@ -133,15 +133,14 @@ struct grub_minix_inode grub_uint32_t indir_zone; grub_uint32_t double_indir_zone; grub_uint32_t unused; - }; #else struct grub_minix_inode { grub_uint16_t mode; grub_uint16_t uid; - grub_uint16_t size; - grub_uint32_t ctime; + grub_uint32_t size; + grub_uint32_t mtime; grub_uint8_t gid; grub_uint8_t nlinks; grub_uint16_t dir_zones[7]; @@ -168,15 +167,19 @@ static grub_dl_t my_mod; static grub_err_t grub_minix_find_file (struct grub_minix_data *data, const char *path); -static int +static grub_minix_uintn_t grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) { - int indir; + grub_minix_uintn_t indir; + const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ + / GRUB_MINIX_INODE_BLKSZ (data)); - auto int grub_get_indir (int, int); + auto grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t, + grub_minix_uintn_t); /* Read the block pointer in ZONE, on the offset NUM. */ - int grub_get_indir (int zone, int num) + grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t zone, + grub_minix_uintn_t num) { grub_minix_uintn_t indirn; grub_disk_read (data->disk, @@ -192,21 +195,20 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) /* Indirect block. */ blk -= GRUB_MINIX_INODE_DIR_BLOCKS; - if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) + if (blk < block_per_zone) { indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk); return indir; } /* Double indirect block. */ - blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data); - if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) - * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))) + blk -= block_per_zone; + if (blk < block_per_zone * block_per_zone) { indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data), - blk / GRUB_MINIX_ZONESZ); + blk / block_per_zone); - indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ); + indir = grub_get_indir (indir, blk % block_per_zone); return indir; } @@ -536,11 +538,7 @@ grub_minix_dir (grub_device_t device, const char *path, info.dir = ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); info.mtimeset = 1; -#ifndef MODE_MINIX2 - info.mtime = grub_le_to_cpu32 (data->inode.ctime); -#else info.mtime = grub_le_to_cpu32 (data->inode.mtime); -#endif if (hook (filename, &info) ? 1 : 0) break; From 6e536dc8ad96e3ca1ae878a4250ec87d6bdccb71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 16:16:28 +0200 Subject: [PATCH 089/315] Support triple indirect on minix2 and minix3. * grub-core/fs/minix.c (grub_minix_inode) [MODE_MINIX2 || MODE_MINIX3]: Declare triple_indir_zone. (grub_minix_get_file_block) [MODE_MINIX2 || MODE_MINIX3]: Handle triple indirect. --- ChangeLog | 9 +++++++++ grub-core/fs/minix.c | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9065162fe..12117d6a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-24 Vladimir Serbinenko + + Support triple indirect on minix2 and minix3. + + * grub-core/fs/minix.c (grub_minix_inode) [MODE_MINIX2 || MODE_MINIX3]: + Declare triple_indir_zone. + (grub_minix_get_file_block) [MODE_MINIX2 || MODE_MINIX3]: Handle triple + indirect. + 2011-10-24 Vladimir Serbinenko Minix FS fixes. diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 1db2883cd..43785b657 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -132,7 +132,7 @@ struct grub_minix_inode grub_uint32_t dir_zones[7]; grub_uint32_t indir_zone; grub_uint32_t double_indir_zone; - grub_uint32_t unused; + grub_uint32_t triple_indir_zone; }; #else struct grub_minix_inode @@ -213,6 +213,20 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) return indir; } +#if defined (MODE_MINIX3) || defined (MODE_MINIX2) + blk -= block_per_zone * block_per_zone; + if (blk < ((grub_uint64_t) block_per_zone * (grub_uint64_t) block_per_zone + * (grub_uint64_t) block_per_zone)) + { + indir = grub_get_indir (grub_minix_le_to_cpu_n (data->inode.triple_indir_zone), + (blk / block_per_zone) / block_per_zone); + indir = grub_get_indir (indir, (blk / block_per_zone) % block_per_zone); + indir = grub_get_indir (indir, blk % block_per_zone); + + return indir; + } +#endif + /* This should never happen. */ grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size"); From 68c72069d927f5f7c907de32d4d9fa43d453c78c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 17:02:02 +0200 Subject: [PATCH 090/315] * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. (grub_jfs_blkno): Fix incorrect shift. (grub_jfs_read_file): Use more appropriate types. --- ChangeLog | 6 ++++++ grub-core/fs/jfs.c | 18 +++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12117d6a0..7d216e1d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-24 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. + (grub_jfs_blkno): Fix incorrect shift. + (grub_jfs_read_file): Use more appropriate types. + 2011-10-24 Vladimir Serbinenko Support triple indirect on minix2 and minix3. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index ebc2c688a..4a7bb0214 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -253,11 +253,11 @@ static grub_int64_t grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, grub_uint64_t blk) { - auto int getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents); + auto grub_int64_t getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents); - int getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents) + grub_int64_t getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents) { int found = -1; int i; @@ -269,7 +269,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, /* Read the leafnode. */ if (grub_le_to_cpu32 (extents[i].offset2) <= blk && ((grub_le_to_cpu16 (extents[i].extent.length)) - + (extents[i].extent.length2 << 8) + + (extents[i].extent.length2 << 16) + grub_le_to_cpu32 (extents[i].offset2)) > blk) return (blk - grub_le_to_cpu32 (extents[i].offset2) + grub_le_to_cpu32 (extents[i].extent.blk2)); @@ -288,7 +288,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, } tree; if (grub_disk_read (data->disk, - grub_le_to_cpu32 (extents[found].extent.blk2) + ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) << (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS), 0, sizeof (tree), (char *) &tree)) @@ -558,10 +558,10 @@ static grub_ssize_t grub_jfs_read_file (struct grub_jfs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - grub_uint64_t pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { - grub_uint64_t i; - grub_uint64_t blockcnt; + grub_off_t i; + grub_off_t blockcnt; blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) >> grub_le_to_cpu16 (data->sblock.log2_blksz); From 5bbd28b8cebbb365faebccf25119a2e6712731ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 21:33:35 +0200 Subject: [PATCH 091/315] Fix 2G limit on ZFS. * grub-core/fs/zfs/zfs.c (zio_checksum_verify): Use more appropriate types. (uberblock_verify): Likewise. (dmu_read): Likewise. (grub_zfs_read): Likewise. Remove invalid cast. --- ChangeLog | 10 ++++++++++ grub-core/fs/zfs/zfs.c | 11 ++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d216e1d7..e8cd7ea77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-24 Vladimir Serbinenko + + Fix 2G limit on ZFS. + + * grub-core/fs/zfs/zfs.c (zio_checksum_verify): Use more appropriate + types. + (uberblock_verify): Likewise. + (dmu_read): Likewise. + (grub_zfs_read): Likewise. Remove invalid cast. + 2011-10-24 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1eea13b26..9d6ad7055 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -242,7 +242,7 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, char *buf, int size) + grub_zfs_endian_t endian, char *buf, grub_size_t size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; @@ -337,7 +337,7 @@ vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) * */ static grub_err_t -uberblock_verify (uberblock_phys_t * ub, int offset) +uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset) { uberblock_t *uber = &ub->ubp_uberblock; grub_err_t err; @@ -620,7 +620,8 @@ static grub_err_t dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, grub_zfs_endian_t *endian_out, struct grub_zfs_data *data) { - int idx, level; + int level; + grub_off_t idx; blkptr_t *bp_array = dn->dn.dn_blkptr; int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; blkptr_t *bp; @@ -2266,7 +2267,7 @@ static grub_ssize_t grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_zfs_data *data = (struct grub_zfs_data *) file->data; - int blksz, movesize; + grub_size_t blksz, movesize; grub_size_t length; grub_size_t read; grub_err_t err; @@ -2320,7 +2321,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) data->file_start = blkid * blksz; data->file_end = data->file_start + blksz; - movesize = MIN (length, data->file_end - (int) file->offset - read); + movesize = MIN (length, data->file_end - file->offset - read); grub_memmove (buf, data->file_buf + file->offset + read - data->file_start, movesize); From f4d9b64bba4e748922056437f0408071376c66b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 17:38:22 +0200 Subject: [PATCH 092/315] * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. --- ChangeLog | 4 ++++ grub-core/fs/romfs.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index e8cd7ea77..1b1975215 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. + 2011-10-24 Vladimir Serbinenko Fix 2G limit on ZFS. diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 58dc98f34..713e8293f 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -367,6 +367,7 @@ grub_romfs_open (struct grub_file *file, const char *name) file->size = grub_be_to_cpu32 (fdiro->file.size); file->data = fdiro; + return GRUB_ERR_NONE; fail: grub_free (data); From 9f326fba96eb04658e7720585e8ad9c643631ced Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:01:57 +0200 Subject: [PATCH 093/315] * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. --- ChangeLog | 4 ++++ grub-core/kern/disk.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1b1975215..7eef0f796 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index f296b9d0f..460d8778f 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -442,6 +442,7 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, } } + grub_free (tmp_buf); grub_errno = GRUB_ERR_NONE; { @@ -468,9 +469,11 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, grub_error_push (); grub_dprintf ("disk", "%s read failed\n", disk->name); grub_error_pop (); + grub_free (tmp_buf); return grub_errno; } grub_memcpy (buf, tmp_buf + offset, size); + grub_free (tmp_buf); return GRUB_ERR_NONE; } } From 9f12e664cc1b815cc01000cf87559a3c303de2e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:09:00 +0200 Subject: [PATCH 094/315] Fix handling of uncompressed blocks on squashfs and break 4G limit. * grub-core/fs/squash4.c (grub_squash_super): Add block_size. Remove unused flags. (grub_squash_inode): Add long_file and block_size. (grub_squash_cache_inode): New struct. (grub_squash_dirent): Make types into enum. (SQUASH_TYPE_LONG_REGULAR): New type. (grub_squash_frag_desc): Add field size. (SQUASH_BLOCK_FLAGS): New enum. (grub_squash_data): Use grub_squash_cache_inode. (grub_fshelp_node): Make ino_chunk 64-bit. (read_chunk): Minor argument change. All users updated. (squash_mount): Use correct le_to_cpu. (grub_squash_open): Handle LONG_REGULAR. (direct_read): New function. (grub_squash_read_data): Handle blocks correctly. --- ChangeLog | 20 ++++ grub-core/fs/squash4.c | 254 ++++++++++++++++++++++++++++++++--------- 2 files changed, 223 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7eef0f796..586de218f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-10-25 Vladimir Serbinenko + + Fix handling of uncompressed blocks on squashfs and break 4G limit. + + * grub-core/fs/squash4.c (grub_squash_super): Add block_size. Remove + unused flags. + (grub_squash_inode): Add long_file and block_size. + (grub_squash_cache_inode): New struct. + (grub_squash_dirent): Make types into enum. + (SQUASH_TYPE_LONG_REGULAR): New type. + (grub_squash_frag_desc): Add field size. + (SQUASH_BLOCK_FLAGS): New enum. + (grub_squash_data): Use grub_squash_cache_inode. + (grub_fshelp_node): Make ino_chunk 64-bit. + (read_chunk): Minor argument change. All users updated. + (squash_mount): Use correct le_to_cpu. + (grub_squash_open): Handle LONG_REGULAR. + (direct_read): New function. + (grub_squash_read_data): Handle blocks correctly. + 2011-10-25 Vladimir Serbinenko * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 4f1265582..d45732c16 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -42,7 +42,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); exttblptr RAW superblock UID/GID table is the array ot uint32_t - unk1 contains pointer to unk3 followed by some chunk. + unk1 contains pointer to fragment table followed by some chunk. unk2 containts one uint64_t */ @@ -52,13 +52,9 @@ struct grub_squash_super #define SQUASH_MAGIC 0x73717368 grub_uint32_t dummy1; grub_uint32_t creation_time; - grub_uint32_t dummy2; + grub_uint32_t block_size; grub_uint64_t dummy3; - grub_uint8_t flags; -#define SQUASH_FLAG_UNCOMPRESSED_INODES 1 -#define SQUASH_FLAG_UNCOMPRESSED_DATA 2 -#define SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS 8 - grub_uint8_t dummy4[7]; + grub_uint64_t dummy4; grub_uint16_t root_ino_offset; grub_uint32_t root_ino_chunk; grub_uint16_t dummy5; @@ -71,7 +67,6 @@ struct grub_squash_super grub_uint64_t unk2offset; } __attribute__ ((packed)); - /* Chunk-based */ struct grub_squash_inode { @@ -87,7 +82,18 @@ struct grub_squash_inode grub_uint32_t fragment; grub_uint32_t offset; grub_uint32_t size; + grub_uint32_t block_size[0]; } __attribute__ ((packed)) file; + struct { + grub_uint32_t dummy; + grub_uint64_t chunk; + grub_uint64_t size; + grub_uint32_t dummy2[3]; + grub_uint32_t fragment; + grub_uint32_t offset; + grub_uint32_t dummy3; + grub_uint32_t block_size[0]; + } __attribute__ ((packed)) long_file; struct { grub_uint32_t dummy1; grub_uint32_t chunk; @@ -104,6 +110,15 @@ struct grub_squash_inode } __attribute__ ((packed)); } __attribute__ ((packed)); +struct grub_squash_cache_inode +{ + struct grub_squash_inode ino; + grub_disk_addr_t ino_chunk; + grub_uint16_t ino_offset; + grub_uint32_t *block_sizes; + grub_disk_addr_t *cumulated_block_sizes; +}; + /* Chunk-based. */ struct grub_squash_dirent_header { @@ -117,29 +132,46 @@ struct grub_squash_dirent grub_uint16_t ino_offset; grub_uint16_t dummy; grub_uint16_t type; -#define SQUASH_TYPE_DIR 1 -#define SQUASH_TYPE_REGULAR 2 -#define SQUASH_TYPE_SYMLINK 3 /* Actually the value is the length of name - 1. */ grub_uint16_t namelen; char name[0]; } __attribute__ ((packed)); +enum + { + SQUASH_TYPE_DIR = 1, + SQUASH_TYPE_REGULAR = 2, + SQUASH_TYPE_SYMLINK = 3, + SQUASH_TYPE_LONG_REGULAR = 9, + }; + + struct grub_squash_frag_desc { grub_uint64_t offset; - grub_uint64_t dummy; + grub_uint32_t size; + grub_uint32_t dummy; } __attribute__ ((packed)); +enum + { + SQUASH_CHUNK_FLAGS = 0x8000, + SQUASH_CHUNK_UNCOMPRESSED = 0x8000 + }; + +enum + { + SQUASH_BLOCK_FLAGS = 0x1000000, + SQUASH_BLOCK_UNCOMPRESSED = 0x1000000 + }; + #define SQUASH_CHUNK_SIZE 0x2000 -#define SQUASH_CHUNK_FLAGS 0x8000 -#define SQUASH_CHUNK_UNCOMPRESSED 0x8000 struct grub_squash_data { grub_disk_t disk; struct grub_squash_super sb; - struct grub_squash_inode ino; + struct grub_squash_cache_inode ino; grub_uint64_t fragments; }; @@ -147,12 +179,12 @@ struct grub_fshelp_node { struct grub_squash_data *data; struct grub_squash_inode ino; - grub_uint32_t ino_chunk; + grub_disk_addr_t ino_chunk; grub_uint16_t ino_offset; }; static grub_err_t -read_chunk (grub_disk_t disk, void *buf, grub_size_t len, +read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, grub_uint64_t chunk, grub_off_t offset) { grub_uint64_t chunk_start; @@ -164,7 +196,8 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, grub_err_t err; while (1) { - err = grub_disk_read (disk, chunk_start >> GRUB_DISK_SECTOR_BITS, + err = grub_disk_read (data->disk, + chunk_start >> GRUB_DISK_SECTOR_BITS, chunk_start & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (d), &d); if (err) @@ -182,7 +215,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED) { grub_disk_addr_t a = chunk_start + 2 + offset; - err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS), + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), a & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); if (err) @@ -197,7 +230,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, if (!tmp) return grub_errno; /* FIXME: buffer uncompressed data. */ - err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS), + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), a & (GRUB_DISK_SECTOR_SIZE - 1), bsize, tmp); if (err) @@ -240,9 +273,10 @@ squash_mount (grub_disk_t disk) return NULL; } - err = grub_disk_read (disk, grub_le_to_cpu32 (sb.unk1offset) + err = grub_disk_read (disk, + grub_le_to_cpu64 (sb.unk1offset) >> GRUB_DISK_SECTOR_BITS, - grub_le_to_cpu32 (sb.unk1offset) + grub_le_to_cpu64 (sb.unk1offset) & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag); if (grub_errno == GRUB_ERR_OUT_OF_RANGE) grub_error (GRUB_ERR_BAD_FS, "not a squash4"); @@ -254,7 +288,7 @@ squash_mount (grub_disk_t disk) return NULL; data->sb = sb; data->disk = disk; - data->fragments = frag; + data->fragments = grub_le_to_cpu64 (frag); return data; } @@ -266,7 +300,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node) grub_err_t err; ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); - err = read_chunk (node->data->disk, ret, + err = read_chunk (node->data, ret, grub_le_to_cpu32 (node->ino.symlink.namelen), grub_le_to_cpu64 (node->data->sb.inodeoffset) + node->ino_chunk, @@ -300,7 +334,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_dirent_header dh; grub_err_t err; - err = read_chunk (dir->data->disk, &dh, sizeof (dh), + err = read_chunk (dir->data, &dh, sizeof (dh), grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) @@ -315,14 +349,14 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_dirent di; struct grub_squash_inode ino; - err = read_chunk (dir->data->disk, &di, sizeof (di), + err = read_chunk (dir->data, &di, sizeof (di), grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) return 0; off += sizeof (di); - err = read_chunk (dir->data->disk, &ino, sizeof (ino), + err = read_chunk (dir->data, &ino, sizeof (ino), grub_le_to_cpu64 (dir->data->sb.inodeoffset) + grub_le_to_cpu32 (dh.ino_chunk), grub_cpu_to_le16 (di.ino_offset)); @@ -332,7 +366,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2); if (!buf) return 0; - err = read_chunk (dir->data->disk, buf, + err = read_chunk (dir->data, buf, grub_le_to_cpu16 (di.namelen) + 1, grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); @@ -370,7 +404,7 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) grub_memset (root, 0, sizeof (*root)); root->data = data; - return read_chunk (data->disk, &root->ino, sizeof (root->ino), + return read_chunk (data, &root->ino, sizeof (root->ino), grub_le_to_cpu64 (data->sb.inodeoffset) + grub_le_to_cpu16 (data->sb.root_ino_chunk), grub_cpu_to_le16 (data->sb.root_ino_offset)); @@ -445,48 +479,166 @@ grub_squash_open (struct grub_file *file, const char *name) } file->data = data; - data->ino = fdiro->ino; - file->size = grub_le_to_cpu32 (fdiro->ino.file.size); + data->ino.ino = fdiro->ino; + data->ino.block_sizes = NULL; + data->ino.cumulated_block_sizes = NULL; + data->ino.ino_chunk = fdiro->ino_chunk; + data->ino.ino_offset = fdiro->ino_offset; + + if (fdiro->ino.type + == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size); + else + file->size = grub_le_to_cpu32 (fdiro->ino.file.size); return GRUB_ERR_NONE; } +static grub_ssize_t +direct_read (struct grub_squash_data *data, + struct grub_squash_cache_inode *ino, + grub_off_t off, char *buf, grub_size_t len) +{ + grub_err_t err; + grub_off_t cumulated_uncompressed_size = 0; + grub_uint64_t a; + grub_size_t i; + grub_size_t origlen = len; + + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + a = grub_le_to_cpu64 (ino->ino.long_file.chunk); + else + a = grub_le_to_cpu32 (ino->ino.file.chunk); + + if (!ino->block_sizes) + { + grub_off_t total_size; + grub_size_t total_blocks; + grub_size_t block_offset; + if (ino->ino.type + == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + { + total_size = grub_le_to_cpu64 (ino->ino.long_file.size); + block_offset = ((char *) &ino->ino.long_file.block_size + - (char *) &ino->ino); + } + else + { + total_size = grub_le_to_cpu32 (ino->ino.file.size); + block_offset = ((char *) &ino->ino.file.block_size + - (char *) &ino->ino); + } + total_blocks = grub_divmod64 (total_size + + grub_le_to_cpu32 (data->sb.block_size) - 1, + grub_le_to_cpu32 (data->sb.block_size), + 0); + ino->block_sizes = grub_malloc (total_blocks + * sizeof (ino->block_sizes[0])); + ino->cumulated_block_sizes = grub_malloc (total_blocks + * sizeof (ino->cumulated_block_sizes[0])); + if (!ino->block_sizes || !ino->cumulated_block_sizes) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + err = read_chunk (data, ino->block_sizes, + total_blocks * sizeof (ino->block_sizes[0]), + grub_le_to_cpu64 (data->sb.inodeoffset) + + ino->ino_chunk, + ino->ino_offset + block_offset); + if (err) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + ino->cumulated_block_sizes[0] = 0; + for (i = 1; i < total_blocks; i++) + ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1] + + (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS); + } + + if (a == 0) + a = sizeof (struct grub_squash_super); + i = grub_divmod64 (off, grub_le_to_cpu32 (data->sb.block_size), 0); + cumulated_uncompressed_size = grub_le_to_cpu32 (data->sb.block_size) + * (grub_disk_addr_t) i; + while (cumulated_uncompressed_size < off + len) + { + grub_size_t boff, read; + boff = off - cumulated_uncompressed_size; + read = grub_le_to_cpu32 (data->sb.block_size) - boff; + if (read > len) + read = len; + if (!(ino->block_sizes[i] & SQUASH_BLOCK_UNCOMPRESSED)) + err = grub_zlib_disk_read (data->disk, + ino->cumulated_block_sizes[i] + a, + boff, buf, read); + else + err = grub_disk_read (data->disk, + (ino->cumulated_block_sizes[i] + a + boff) + >> GRUB_DISK_SECTOR_BITS, + (ino->cumulated_block_sizes[i] + a + boff) + & (GRUB_DISK_SECTOR_SIZE - 1), + read, buf); + if (err) + return -1; + off += read; + len -= read; + buf += read; + cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size); + i++; + } + return origlen; +} + + static grub_ssize_t grub_squash_read_data (struct grub_squash_data *data, - grub_disk_t disk, const struct grub_squash_inode *ino, + struct grub_squash_cache_inode *ino, grub_off_t off, char *buf, grub_size_t len) { grub_err_t err; grub_uint64_t a, b; + grub_uint32_t fragment; int compressed = 0; + struct grub_squash_frag_desc frag; - if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff) + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) { - if (grub_le_to_cpu32 (ino->file.chunk)) - a = grub_le_to_cpu32 (ino->file.chunk); - else - a = sizeof (struct grub_squash_super); - compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA); + a = grub_le_to_cpu64 (ino->ino.long_file.chunk); + fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment); } else { - struct grub_squash_frag_desc frag; - err = read_chunk (disk, &frag, sizeof (frag), - data->fragments, sizeof (frag) - * grub_le_to_cpu16 (ino->file.fragment)); - if (err) - return -1; - a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk); - compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); + a = grub_le_to_cpu32 (ino->ino.file.chunk); + fragment = grub_le_to_cpu32 (ino->ino.file.fragment); } - b = grub_le_to_cpu32 (data->ino.file.offset) + off; - + if (fragment == 0xffffffff) + return direct_read (data, ino, off, buf, len); + + err = read_chunk (data, &frag, sizeof (frag), + data->fragments, sizeof (frag) * fragment); + if (err) + return -1; + a += grub_le_to_cpu64 (frag.offset); + compressed = !(frag.size & SQUASH_BLOCK_UNCOMPRESSED); + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + b = grub_le_to_cpu64 (ino->ino.long_file.offset) + off; + else + b = grub_le_to_cpu32 (ino->ino.file.offset) + off; + /* FIXME: cache uncompressed chunks. */ if (compressed) - err = grub_zlib_disk_read (disk, a, b, buf, len); + err = grub_zlib_disk_read (data->disk, a, b, buf, len); else - err = grub_disk_read (disk, (a + b) >> GRUB_DISK_SECTOR_BITS, + err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); if (err) return -1; @@ -498,7 +650,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_squash_data *data = file->data; - return grub_squash_read_data (data, file->device->disk, &data->ino, + return grub_squash_read_data (data, &data->ino, file->offset, buf, len); } From d4888031f2577c86f354393bf4e2e5f22ea25bd4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:12:36 +0200 Subject: [PATCH 095/315] Fix tar 4G limit and handle paths containing dot. * grub-core/fs/cpio.c (grub_cpio_data): Use grub_off_t for offsets. (canonicalize): New function. (grub_cpio_find_file): Use canonicalize. Store offs in grub_disk_addr_t. (grub_cpio_dir): Use grub_disk_addr_t. (grub_cpio_open): Likewise. --- ChangeLog | 11 ++++ grub-core/fs/cpio.c | 134 ++++++++++++++++++++++++++------------------ 2 files changed, 89 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 586de218f..19bf1326e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-10-25 Vladimir Serbinenko + + Fix tar 4G limit and handle paths containing dot. + + * grub-core/fs/cpio.c (grub_cpio_data): Use grub_off_t for offsets. + (canonicalize): New function. + (grub_cpio_find_file): Use canonicalize. Store offs in + grub_disk_addr_t. + (grub_cpio_dir): Use grub_disk_addr_t. + (grub_cpio_open): Likewise. + 2011-10-25 Vladimir Serbinenko Fix handling of uncompressed blocks on squashfs and break 4G limit. diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 0d84382ac..92531390e 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -71,80 +71,102 @@ struct head struct grub_cpio_data { grub_disk_t disk; - grub_uint32_t hofs; - grub_uint32_t dofs; - grub_uint32_t size; + grub_off_t hofs; + grub_off_t dofs; + grub_off_t size; }; static grub_dl_t my_mod; +static inline void +canonicalize (char *name) +{ + char *iptr, *optr; + for (iptr = name, optr = name; *iptr; ) + { + while (*iptr == '/') + iptr++; + if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0)) + { + iptr += 2; + continue; + } + while (*iptr && *iptr != '/') + *optr++ = *iptr++; + if (*iptr) + *optr++ = *iptr++; + } + *optr = 0; +} + static grub_err_t grub_cpio_find_file (struct grub_cpio_data *data, char **name, - grub_int32_t *mtime, grub_uint32_t * ofs) + grub_int32_t *mtime, grub_disk_addr_t * ofs) { #ifndef MODE_USTAR - struct head hd; + struct head hd; - if (grub_disk_read - (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; - if (hd.magic != MAGIC_BCPIO) - return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); + if (hd.magic != MAGIC_BCPIO) + return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); - data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; - if (mtime) - *mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2; + data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; + if (mtime) + *mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2; - if (hd.namesize & 1) - hd.namesize++; + if (hd.namesize & 1) + hd.namesize++; - if ((*name = grub_malloc (hd.namesize)) == NULL) - return grub_errno; + if ((*name = grub_malloc (hd.namesize)) == NULL) + return grub_errno; - if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), - hd.namesize, *name)) - { - grub_free (*name); - return grub_errno; - } + if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), + hd.namesize, *name)) + { + grub_free (*name); + return grub_errno; + } - if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 - && ! grub_memcmp(*name, "TRAILER!!!", 11)) - { - *ofs = 0; - return GRUB_ERR_NONE; - } + if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 + && ! grub_memcmp(*name, "TRAILER!!!", 11)) + { + *ofs = 0; + return GRUB_ERR_NONE; + } - data->dofs = data->hofs + sizeof (hd) + hd.namesize; - *ofs = data->dofs + data->size; - if (data->size & 1) - (*ofs)++; + canonicalize (*name); + + data->dofs = data->hofs + sizeof (hd) + hd.namesize; + *ofs = data->dofs + data->size; + if (data->size & 1) + (*ofs)++; #else - struct head hd; + struct head hd; - if (grub_disk_read - (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; - if (!hd.name[0]) - { - *ofs = 0; - return GRUB_ERR_NONE; - } + if (!hd.name[0]) + { + *ofs = 0; + return GRUB_ERR_NONE; + } - if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); + if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - if ((*name = grub_strdup (hd.name)) == NULL) - return grub_errno; + if ((*name = grub_strdup (hd.name)) == NULL) + return grub_errno; - data->size = grub_strtoul (hd.size, NULL, 8); - data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; - *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & - ~(GRUB_DISK_SECTOR_SIZE - 1)); - if (mtime) - *mtime = grub_strtoul (hd.mtime, NULL, 8); + data->size = grub_strtoull (hd.size, NULL, 8); + data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; + *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + if (mtime) + *mtime = grub_strtoul (hd.mtime, NULL, 8); + canonicalize (*name); #endif return GRUB_ERR_NONE; } @@ -191,10 +213,10 @@ grub_cpio_dir (grub_device_t device, const char *path, const struct grub_dirhook_info *info)) { struct grub_cpio_data *data; - grub_uint32_t ofs; + grub_disk_addr_t ofs; char *prev, *name; const char *np; - int len; + grub_size_t len; grub_dl_ref (my_mod); @@ -230,7 +252,7 @@ grub_cpio_dir (grub_device_t device, const char *path, if (p) *p = 0; - if ((!prev) || (grub_strcmp (prev, name) != 0)) + if (((!prev) || (grub_strcmp (prev, name) != 0)) && name[len] != 0) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -262,7 +284,7 @@ static grub_err_t grub_cpio_open (grub_file_t file, const char *name) { struct grub_cpio_data *data; - grub_uint32_t ofs; + grub_disk_addr_t ofs; char *fn; int i, j; From e12119495df2f7213169985c10889ec46b205b8e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:18:58 +0200 Subject: [PATCH 096/315] Support multi-extent iso files. * grub-core/fs/iso9660.c (grub_iso9660_data): Remove first_sector. Add node. (grub_fshelp_node): Revamp. All users updated. (FLAG_*): New enum. (read_node): New function. (grub_iso9660_susp_iterate): Use read_node. Receive a node as argument. All users updated. (grub_iso9660_mount): Don't attempt to read sua when there is none. (get_node_size): New function. (grub_iso9660_iterate_dir): Use read_node. Agglomerate multi-extent entries. Fix memory leak on . and .. (grub_iso9660_read): Use read_node. (grub_iso9660_close): Free node. --- ChangeLog | 19 ++++ grub-core/fs/iso9660.c | 208 +++++++++++++++++++++++++++++------------ 2 files changed, 167 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19bf1326e..a9b26a313 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-10-25 Vladimir Serbinenko + + Support multi-extent iso files. + + * grub-core/fs/iso9660.c (grub_iso9660_data): Remove first_sector. + Add node. + (grub_fshelp_node): Revamp. All users updated. + (FLAG_*): New enum. + (read_node): New function. + (grub_iso9660_susp_iterate): Use read_node. Receive a node as argument. + All users updated. + (grub_iso9660_mount): Don't attempt to read sua when there is none. + (get_node_size): New function. + (grub_iso9660_iterate_dir): Use read_node. Agglomerate multi-extent + entries. + Fix memory leak on . and .. + (grub_iso9660_read): Use read_node. + (grub_iso9660_close): Free node. + 2011-10-25 Vladimir Serbinenko Fix tar 4G limit and handle paths containing dot. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 5b53ca597..f6cbbca95 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -149,22 +149,28 @@ struct grub_iso9660_data { struct grub_iso9660_primary_voldesc voldesc; grub_disk_t disk; - unsigned int first_sector; int rockridge; int susp_skip; int joliet; + struct grub_fshelp_node *node; }; struct grub_fshelp_node { struct grub_iso9660_data *data; - struct grub_iso9660_dir dirent; - unsigned int size; - unsigned int blk; - unsigned int dir_blk; - unsigned int dir_off; + grub_size_t have_dirents, alloc_dirents; + grub_off_t dir_off; + struct grub_iso9660_dir dirents[8]; }; +enum + { + FLAG_TYPE_PLAIN = 0, + FLAG_TYPE_DIR = 2, + FLAG_TYPE = 3, + FLAG_MORE_EXTENTS = 0x80 + }; + static grub_dl_t my_mod; @@ -214,30 +220,69 @@ iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) return 1; } +static grub_err_t +read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) +{ + grub_size_t i = 0; + + while (len > 0) + { + grub_size_t toread; + grub_err_t err; + while (i < node->have_dirents + && off >= grub_le_to_cpu32 (node->dirents[i].size)) + { + off -= grub_le_to_cpu32 (node->dirents[i].size); + i++; + } + if (i == node->have_dirents) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); + toread = grub_le_to_cpu32 (node->dirents[i].size); + if (toread > len) + toread = len; + err = grub_disk_read (node->data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ, + off, toread, buf); + if (err) + return err; + len -= toread; + off += toread; + buf += toread; + } + return GRUB_ERR_NONE; +} + /* Iterate over the susp entries, starting with block SUA_BLOCK on the offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ static grub_err_t -grub_iso9660_susp_iterate (struct grub_iso9660_data *data, - int sua_block, int sua_pos, int sua_size, +grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_size_t sua_size, grub_err_t (*hook) (struct grub_iso9660_susp_entry *entry)) { char *sua; struct grub_iso9660_susp_entry *entry; + grub_disk_addr_t ce_block; + int is_ce = 0; auto grub_err_t load_sua (void); /* Load a part of the System Usage Area. */ grub_err_t load_sua (void) { + grub_err_t err; sua = grub_malloc (sua_size); if (!sua) return grub_errno; - if (grub_disk_read (data->disk, sua_block, sua_pos, - sua_size, sua)) - return grub_errno; + if (is_ce) + err = grub_disk_read (node->data->disk, ce_block, off, + sua_size, sua); + else + err = read_node (node, off, sua_size, sua); + if (err) + return err; entry = (struct grub_iso9660_susp_entry *) sua; return 0; @@ -259,10 +304,11 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data, { struct grub_iso9660_susp_ce *ce; + is_ce = 1; ce = (struct grub_iso9660_susp_ce *) entry; sua_size = grub_le_to_cpu32 (ce->len); - sua_pos = grub_le_to_cpu32 (ce->off); - sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; grub_free (sua); if (load_sua ()) @@ -383,6 +429,9 @@ grub_iso9660_mount (grub_disk_t disk) + (rootdir.namelen % 2) - 1); sua_size = rootdir.len - sua_pos; + if (!sua_size) + return data; + sua = grub_malloc (sua_size); if (! sua) goto fail; @@ -400,6 +449,14 @@ grub_iso9660_mount (grub_disk_t disk) /* Test if the SUSP protocol is used on this filesystem. */ if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + /* The 2nd data byte stored how many bytes are skipped every time to get to the SUA (System Usage Area). */ data->susp_skip = entry->data[2]; @@ -407,9 +464,7 @@ grub_iso9660_mount (grub_disk_t disk) /* Iterate over the entries in the SUA area to detect extensions. */ - if (grub_iso9660_susp_iterate (data, - (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), + if (grub_iso9660_susp_iterate (&rootnode, sua_pos, sua_size, susp_iterate)) goto fail; } @@ -502,10 +557,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) return 0; } - sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1 - - (node->dirent.namelen % 2) + sua_off = (sizeof (node->dirents[0]) + node->dirents[0].namelen + 1 + - (node->dirents[0].namelen % 2) + node->data->susp_skip); - sua_size = node->dirent.len - sua_off; + sua_size = node->dirents[0].len - sua_off; symlink = grub_malloc (1); if (!symlink) @@ -513,8 +568,7 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) *symlink = '\0'; - if (grub_iso9660_susp_iterate (node->data, node->dir_blk, - node->dir_off + sua_off, + if (grub_iso9660_susp_iterate (node, node->dir_off + sua_off, sua_size, susp_iterate_sl)) { grub_free (symlink); @@ -524,6 +578,16 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) return symlink; } +static grub_off_t +get_node_size (grub_fshelp_node_t node) +{ + grub_off_t ret = 0; + grub_size_t i; + + for (i = 0; i < node->have_dirents; i++) + ret += grub_le_to_cpu32 (node->dirents[i].size); + return ret; +} static int grub_iso9660_iterate_dir (grub_fshelp_node_t dir, @@ -533,10 +597,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_node_t node)) { struct grub_iso9660_dir dirent; - unsigned int offset = 0; + grub_off_t offset = 0; char *filename; int filename_alloc = 0; enum grub_fshelp_filetype type; + grub_off_t len; auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); @@ -598,13 +663,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, return 0; } - for (; offset < dir->size; offset += dirent.len) + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) { - if (grub_disk_read (dir->data->disk, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + offset / GRUB_DISK_SECTOR_SIZE, - offset % GRUB_DISK_SECTOR_SIZE, - sizeof (dirent), (char *) &dirent)) + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; /* The end of the block, skip to the next one. */ @@ -629,39 +692,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, type = GRUB_FSHELP_UNKNOWN; if (dir->data->rockridge - && grub_iso9660_susp_iterate (dir->data, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + (sua_off - / GRUB_DISK_SECTOR_SIZE), - sua_off % GRUB_DISK_SECTOR_SIZE, - sua_size, susp_iterate_dir)) + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, + susp_iterate_dir)) return 0; /* Read the name. */ - if (grub_disk_read (dir->data->disk, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + nameoffset / GRUB_DISK_SECTOR_SIZE, - nameoffset % GRUB_DISK_SECTOR_SIZE, - dirent.namelen, (char *) name)) + if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) return 0; node = grub_malloc (sizeof (struct grub_fshelp_node)); if (!node) return 0; + node->alloc_dirents = ARRAY_SIZE (node->dirents); + node->have_dirents = 1; + /* Setup a new node. */ node->data = dir->data; - node->size = grub_le_to_cpu32 (dirent.size); - node->blk = grub_le_to_cpu32 (dirent.first_sector); - node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + offset / GRUB_DISK_SECTOR_SIZE); - node->dir_off = offset % GRUB_DISK_SECTOR_SIZE; + node->dir_off = offset; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ if (type == GRUB_FSHELP_UNKNOWN) { - if ((dirent.flags & 3) == 2) + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) type = GRUB_FSHELP_DIR; else type = GRUB_FSHELP_REG; @@ -678,7 +732,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* . and .. */ if (dirent.namelen == 1 && (name[0] == 0 || name[0] == 1)) - continue; + { + grub_free (node); + continue; + } else filename = name; } @@ -701,7 +758,35 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename_alloc = 1; } - node->dirent = dirent; + node->dirents[0] = dirent; + while (dirent.flags & FLAG_MORE_EXTENTS) + { + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; + node->alloc_dirents *= 2; + new_node = grub_malloc (sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); + if (!new_node) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + } + node->dirents[node->have_dirents++] = dirent; + } if (hook (filename, type, node)) { if (filename_alloc) @@ -738,7 +823,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - info.mtimeset = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime); + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); grub_free (node); return hook (filename, &info); @@ -751,8 +836,10 @@ grub_iso9660_dir (grub_device_t device, const char *path, goto fail; rootnode.data = data; - rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); - rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ if (grub_fshelp_find_file (path, &rootnode, @@ -792,8 +879,10 @@ grub_iso9660_open (struct grub_file *file, const char *name) goto fail; rootnode.data = data; - rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); - rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ if (grub_fshelp_find_file (name, &rootnode, @@ -803,10 +892,9 @@ grub_iso9660_open (struct grub_file *file, const char *name) GRUB_FSHELP_REG)) goto fail; - data->first_sector = foundnode->blk; - + data->node = foundnode; file->data = data; - file->size = foundnode->size; + file->size = get_node_size (foundnode); file->offset = 0; return 0; @@ -828,10 +916,7 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) /* XXX: The file is stored in as a single extent. */ data->disk->read_hook = file->read_hook; - grub_disk_read (data->disk, - data->first_sector << GRUB_ISO9660_LOG2_BLKSZ, - file->offset, - len, buf); + read_node (data->node, file->offset, len, buf); data->disk->read_hook = NULL; if (grub_errno) @@ -844,7 +929,10 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_iso9660_close (grub_file_t file) { - grub_free (file->data); + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_free (data->node); + grub_free (data); grub_dl_unref (my_mod); From db82136381f991edb8fe9bb28406a03ec1d19e2d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:20:39 +0200 Subject: [PATCH 097/315] * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): Use union to avoid breaking strict-aliasing rules. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsd.c | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9b26a313..8c8af24e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): + Use union to avoid breaking strict-aliasing rules. + 2011-10-25 Vladimir Serbinenko Support multi-extent iso files. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 18ebeb760..f2d0845f8 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -960,8 +960,10 @@ grub_netbsd_add_boot_disk_and_wedge (void) grub_partition_t part; grub_uint32_t biosdev; grub_uint32_t partmapsector; - struct grub_partition_bsd_disk_label *label; - grub_uint64_t buf[GRUB_DISK_SECTOR_SIZE / 8]; + union { + grub_uint64_t raw[GRUB_DISK_SECTOR_SIZE / 8]; + struct grub_partition_bsd_disk_label label; + } buf; grub_uint8_t *hash; grub_uint64_t ctx[(GRUB_MD_MD5->contextsize + 7) / 8]; @@ -981,7 +983,8 @@ grub_netbsd_add_boot_disk_and_wedge (void) partmapsector = grub_partition_get_start (part->parent) + part->offset; disk->partition = part->parent; - if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf) != GRUB_ERR_NONE) + if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf.raw) + != GRUB_ERR_NONE) goto fail; disk->partition = part; @@ -997,7 +1000,7 @@ grub_netbsd_add_boot_disk_and_wedge (void) biw.matchnblks = 1; GRUB_MD_MD5->init (&ctx); - GRUB_MD_MD5->write (&ctx, buf, GRUB_DISK_SECTOR_SIZE); + GRUB_MD_MD5->write (&ctx, buf.raw, GRUB_DISK_SECTOR_SIZE); GRUB_MD_MD5->final (&ctx); hash = GRUB_MD_MD5->read (&ctx); memcpy (biw.matchhash, hash, 16); @@ -1006,18 +1009,17 @@ grub_netbsd_add_boot_disk_and_wedge (void) } /* Fill bootdisk if this a NetBSD disk label. */ - label = (struct grub_partition_bsd_disk_label *) &buf; if (part->partmap != NULL && (grub_strcmp (part->partmap->name, "netbsd") == 0) && - label->magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + buf.label.magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) { struct grub_netbsd_btinfo_bootdisk bid; grub_memset (&bid, 0, sizeof (bid)); bid.labelsector = partmapsector; - bid.label.type = label->type; - bid.label.checksum = label->checksum; - memcpy (bid.label.packname, label->packname, 16); + bid.label.type = buf.label.type; + bid.label.checksum = buf.label.checksum; + memcpy (bid.label.packname, buf.label.packname, 16); bid.biosdev = biosdev; bid.partition = part->number; grub_bsd_add_meta (NETBSD_BTINFO_BOOTDISK, &bid, sizeof (bid)); From 66b40850331be5979d85a3d0583c7bd74c704b08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 21:52:48 +0200 Subject: [PATCH 098/315] Fix symlink handling on iso9660. * grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink All users updated. (grub_iso9660_susp_iterate): Accept zero-size iterate. (grub_iso9660_read_symlink): Moved most of code ... (grub_iso9660_iterate_dir): ... here. Fill node->symlink. --- ChangeLog | 10 +++ grub-core/fs/iso9660.c | 182 ++++++++++++++++++----------------------- 2 files changed, 90 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c8af24e4..d40675db7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-25 Vladimir Serbinenko + + Fix symlink handling on iso9660. + + * grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink + All users updated. + (grub_iso9660_susp_iterate): Accept zero-size iterate. + (grub_iso9660_read_symlink): Moved most of code ... + (grub_iso9660_iterate_dir): ... here. Fill node->symlink. + 2011-10-25 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index f6cbbca95..f3e828b89 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -159,7 +159,7 @@ struct grub_fshelp_node { struct grub_iso9660_data *data; grub_size_t have_dirents, alloc_dirents; - grub_off_t dir_off; + char *symlink; struct grub_iso9660_dir dirents[8]; }; @@ -257,7 +257,7 @@ read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) every entry. */ static grub_err_t grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - grub_size_t sua_size, + grub_ssize_t sua_size, grub_err_t (*hook) (struct grub_iso9660_susp_entry *entry)) { @@ -288,6 +288,9 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, return 0; } + if (sua_size <= 0) + return GRUB_ERR_NONE; + if (load_sua ()) return grub_errno; @@ -454,7 +457,7 @@ grub_iso9660_mount (grub_disk_t disk) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* The 2nd data byte stored how many bytes are skipped every time @@ -480,102 +483,7 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - int sua_off; - int sua_size; - char *symlink = 0; - int addslash = 0; - - auto void add_part (const char *part, int len); - auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *); - - /* Extend the symlink. */ - void add_part (const char *part, int len) - { - int size = grub_strlen (symlink); - - symlink = grub_realloc (symlink, size + len + 1); - if (! symlink) - return; - - grub_strncat (symlink, part, len); - } - - /* Read in a symlink. */ - grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry) - { - if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) - { - unsigned int pos = 1; - - /* The symlink is not stored as a POSIX symlink, translate it. */ - while (pos < grub_le_to_cpu32 (entry->len)) - { - if (addslash) - { - add_part ("/", 1); - addslash = 0; - } - - /* The current position is the `Component Flag'. */ - switch (entry->data[pos] & 30) - { - case 0: - { - /* The data on pos + 2 is the actual data, pos + 1 - is the length. Both are part of the `Component - Record'. */ - add_part ((char *) &entry->data[pos + 2], - entry->data[pos + 1]); - if ((entry->data[pos] & 1)) - addslash = 1; - - break; - } - - case 2: - add_part ("./", 2); - break; - - case 4: - add_part ("../", 3); - break; - - case 8: - add_part ("/", 1); - break; - } - /* In pos + 1 the length of the `Component Record' is - stored. */ - pos += entry->data[pos + 1] + 2; - } - - /* Check if `grub_realloc' failed. */ - if (grub_errno) - return grub_errno; - } - - return 0; - } - - sua_off = (sizeof (node->dirents[0]) + node->dirents[0].namelen + 1 - - (node->dirents[0].namelen % 2) - + node->data->susp_skip); - sua_size = node->dirents[0].len - sua_off; - - symlink = grub_malloc (1); - if (!symlink) - return 0; - - *symlink = '\0'; - - if (grub_iso9660_susp_iterate (node, node->dir_off + sua_off, - sua_size, susp_iterate_sl)) - { - grub_free (symlink); - return 0; - } - - return symlink; + return node->symlink ? grub_strdup (node->symlink) : grub_strdup (""); } static grub_off_t @@ -602,6 +510,23 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, int filename_alloc = 0; enum grub_fshelp_filetype type; grub_off_t len; + char *symlink = 0; + int addslash = 0; + + auto void add_part (const char *part, int len); + + /* Extend the symlink. */ + void add_part (const char *part, int len2) + { + int size = symlink ? grub_strlen (symlink) : 0; + + symlink = grub_realloc (symlink, size + len2 + 1); + if (! symlink) + return; + + symlink[size] = 0; + grub_strncat (symlink, part, len2); + } auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); @@ -659,6 +584,56 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, type = GRUB_FSHELP_UNKNOWN; } } + else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len)) + { + if (addslash) + { + add_part ("/", 1); + addslash = 0; + } + + /* The current position is the `Component Flag'. */ + switch (entry->data[pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + add_part ((char *) &entry->data[pos + 2], + entry->data[pos + 1]); + if ((entry->data[pos] & 1)) + addslash = 1; + + break; + } + + case 2: + add_part ("./", 2); + break; + + case 4: + add_part ("../", 3); + break; + + case 8: + add_part ("/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->data[pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } return 0; } @@ -667,6 +642,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, for (; offset < len; offset += dirent.len) { + symlink = 0; + addslash = 0; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; @@ -709,7 +687,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* Setup a new node. */ node->data = dir->data; - node->dir_off = offset; + node->symlink = symlink; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ @@ -838,7 +816,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ @@ -881,7 +859,7 @@ grub_iso9660_open (struct grub_file *file, const char *name) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ From 19832ddb37a6e4a034a2501954fd01a8ff935c73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 21:53:57 +0200 Subject: [PATCH 099/315] * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. --- ChangeLog | 4 ++++ grub-core/fs/fat.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index d40675db7..9f05edaa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. + 2011-10-25 Vladimir Serbinenko Fix symlink handling on iso9660. diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 36a43fca0..fb1113814 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -1117,9 +1117,12 @@ grub_fat_uuid (grub_device_t device, char **uuid) data = grub_fat_mount (disk); if (data) { + char *ptr; *uuid = grub_xasprintf ("%04x-%04x", (grub_uint16_t) (data->uuid >> 16), (grub_uint16_t) data->uuid); + for (ptr = *uuid; ptr && *ptr; ptr++) + *ptr = grub_toupper (*ptr); } else *uuid = NULL; From e9cc6b7b0e26f38b22a72ecc931273b22a9e1d2a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:29:46 +0200 Subject: [PATCH 100/315] * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. --- ChangeLog | 4 ++++ grub-core/fs/ntfs.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f05edaa2..3b0b4697a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 5d128bcc0..6b8455c34 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -1087,14 +1087,15 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) if (*uuid) for (ptr = *uuid; *ptr; ptr++) *ptr = grub_toupper (*ptr); + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); } else *uuid = NULL; grub_dl_unref (my_mod); - grub_free (data); - return grub_errno; } From 67e2bd718e9ddd0571a28358e8928dc320e2d76e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:32:17 +0200 Subject: [PATCH 101/315] Read label on HFS+. * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. (grub_hfsplus_btree_search): Fix types. (grub_hfsplus_label): Implement. --- ChangeLog | 8 ++++ grub-core/fs/hfsplus.c | 87 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b0b4697a..17e215b62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-25 Vladimir Serbinenko + + Read label on HFS+. + + * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. + (grub_hfsplus_btree_search): Fix types. + (grub_hfsplus_label): Implement. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 245cd93a5..3d9bc42fa 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -553,6 +553,25 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, return diff; } +/* Compare the on disk catalog key KEYA with the catalog key we are + looking for (KEYB). */ +static int +grub_hfsplus_cmp_catkey_id (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb) +{ + struct grub_hfsplus_catkey *catkey_a = &keya->catkey; + struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; + + /* Safe unsigned comparison */ + grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent); + if (aparent > catkey_b->parent) + return 1; + if (aparent < catkey_b->parent) + return -1; + + return 0; +} + /* Compare the on disk extent overflow key KEYA with the extent overflow key we are looking for (KEYB). */ static int @@ -662,7 +681,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, /* Read a node. */ if (grub_hfsplus_read_file (&btree->file, 0, - (long)currnode * (long)btree->nodesize, + (grub_disk_addr_t) currnode + * (grub_disk_addr_t) btree->nodesize, btree->nodesize, (char *) node) <= 0) { grub_free (node); @@ -961,13 +981,66 @@ grub_hfsplus_dir (grub_device_t device, const char *path, static grub_err_t -grub_hfsplus_label (grub_device_t device __attribute__((unused)) - , char **label __attribute__((unused))) +grub_hfsplus_label (grub_device_t device, char **label) { - /* XXX: It's not documented how to read a label. */ - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "reading the label of a HFS+ " - "partition is not implemented"); + struct grub_hfsplus_data *data; + grub_disk_t disk = device->disk; + struct grub_hfsplus_catkey *catkey; + int i, label_len; + struct grub_hfsplus_key_internal intern; + struct grub_hfsplus_btnode *node; + grub_disk_addr_t ptr; + + *label = 0; + + data = grub_hfsplus_mount (disk); + if (!data) + return grub_errno; + + /* Create a key that points to the label. */ + intern.catkey.parent = 1; + intern.catkey.name = ""; + + /* First lookup the first entry. */ + if (grub_hfsplus_btree_search (&data->catalog_tree, &intern, + grub_hfsplus_cmp_catkey_id, &node, &ptr)) + { + grub_free (data); + return 0; + } + + catkey = (struct grub_hfsplus_catkey *) + grub_hfsplus_btree_recptr (&data->catalog_tree, node, 0); + + label_len = grub_be_to_cpu16 (catkey->namelen); + for (i = 0; i < label_len; i++) + { + catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + + /* If the name is obviously invalid, skip this node. */ + if (catkey->name[i] == 0) + return 0; + } + + *label = grub_malloc (label_len + 1); + if (! *label) + return grub_errno; + + if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, + label_len)) + { + grub_free (node); + grub_free (*label); + grub_free (data); + *label = 0; + return grub_errno; + } + (*label)[label_len] = '\0'; + + grub_free (node); + grub_free (data); + + return GRUB_ERR_NONE; } /* Get mtime. */ From c0584900ee804a1b8d1a687cfd042321f05f2150 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:35:41 +0200 Subject: [PATCH 102/315] * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. --- ChangeLog | 4 ++++ grub-core/fs/jfs.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17e215b62..683fd53f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. + 2011-10-25 Vladimir Serbinenko Read label on HFS+. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 4a7bb0214..c5e82bfec 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -52,9 +52,9 @@ struct grub_jfs_sblock grub_uint32_t blksz; grub_uint16_t log2_blksz; - grub_uint8_t unused[71]; + grub_uint8_t unused[79]; grub_uint8_t volname[11]; - grub_uint8_t unused2[32]; + grub_uint8_t unused2[24]; grub_uint8_t uuid[16]; }; From 5587329c914465659893d484363d919c1fe35c71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 17:32:21 +0200 Subject: [PATCH 103/315] ZFS fixes. * grub-core/fs/zfs/zfs.c (fzap_iterate): Fix handling of indexes sharing the same block. Iterate over correct number of indices. (dnode_get_path): Handle symlinks correctly. --- ChangeLog | 8 ++++++ grub-core/fs/zfs/zfs.c | 64 +++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 683fd53f3..9787d8f9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-25 Vladimir Serbinenko + + ZFS fixes. + + * grub-core/fs/zfs/zfs.c (fzap_iterate): Fix handling of indexes + sharing the same block. Iterate over correct number of indices. + (dnode_get_path): Handle symlinks correctly. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9d6ad7055..6721cddc1 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -941,7 +941,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, { zap_leaf_phys_t *l; void *l_in; - grub_uint64_t idx, blkid; + grub_uint64_t idx, idx2, blkid; grub_uint16_t chunk; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << DNODE_SHIFT); @@ -964,10 +964,16 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); return 0; } - for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) + for (idx = 0; idx < (1ULL << zap->zap_ptrtbl.zt_shift); idx++) { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + for (idx2 = 0; idx2 < idx; idx2++) + if (blkid == ((grub_uint64_t *) zap)[idx2 + (1 << (blksft - 3 - 1))]) + break; + if (idx2 != idx) + continue; + err = dmu_read (zap_dnode, blkid, &l_in, &endian, data); l = l_in; if (err) @@ -1093,7 +1099,7 @@ zap_iterate (dnode_end_t * zap_dnode, return 0; block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); - grub_dprintf ("zfs", "zap read\n"); + grub_dprintf ("zfs", "zap iterate\n"); if (block_type == ZBT_MICRO) { @@ -1310,22 +1316,55 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; -#if 0 - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) + if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { + char *sym_value; + grub_size_t avail_in_dnode; + grub_size_t sym_sz; + int free_symval = 0; char *oldpath = path, *oldpathbuf = path_buf; - path = path_buf - = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) - - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); + sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys)); + avail_in_dnode = (char *) (&dnode_path->dn + 1) - sym_value; + + sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian); + + if (sym_sz > avail_in_dnode - 8) + { + grub_size_t block; + grub_size_t blksz; + blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, + dnode_path->dn.endian) + << SPA_MINBLOCKSHIFT); + + sym_value = grub_malloc (sym_sz); + if (!sym_value) + return grub_errno; + for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) + { + void *t; + grub_size_t movesize; + + err = dmu_read (&(dnode_path->dn), block, &t, 0, data); + if (err) + return err; + + movesize = MIN (sym_sz - block * blksz, blksz); + + grub_memcpy (sym_value + block * blksz, t, movesize); + grub_free (t); + } + free_symval = 1; + } + path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); if (!path_buf) { grub_free (oldpathbuf); return grub_errno; } - grub_memcpy (path, - (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), - sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); - path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; + grub_memcpy (path, sym_value, sym_sz); + if (free_symval) + grub_free (sym_value); + path [sym_sz] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); @@ -1343,7 +1382,6 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } -#endif } if (!err) From a562fbb48b6934f6dcde9030538a0809016a5acb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 19:11:10 +0200 Subject: [PATCH 104/315] Bump spa version --- include/grub/zfs/zfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index e1759dbbd..374068d06 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -28,7 +28,7 @@ /* * On-disk version number. */ -#define SPA_VERSION 28ULL +#define SPA_VERSION 31ULL /* * The following are configuration names used in the nvlist describing a pool's From 186b402804c37ff3fda5b2a969d071a978194195 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 19:27:36 +0200 Subject: [PATCH 105/315] * include/grub/datetime.h (grub_datetime2unixtime): Fix off-by-one error. --- ChangeLog | 7 ++++++- include/grub/datetime.h | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9787d8f9e..084131202 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2011-10-25 Vladimir Serbinenko +2011-10-26 Vladimir Serbinenko + + * include/grub/datetime.h (grub_datetime2unixtime): Fix off-by-one + error. + +2011-10-26 Vladimir Serbinenko ZFS fixes. diff --git a/include/grub/datetime.h b/include/grub/datetime.h index dea0f8ea9..049dbc227 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -86,13 +86,13 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) are bissextile*/ /* Convenience: let's have 3 consecutive non-bissextile years at the beginning of the epoch. So count from 1971 instead of 1970 */ - ret = SECPERYEAR + SECPERDAY; + ret = 2 * SECPERYEAR + SECPERDAY; /* Transform C divisions and modulos to mathematical ones */ - y4 = (datetime->year - 1971) / 4; - if (datetime->year < 1971) + y4 = (datetime->year - 1972) / 4; + if (datetime->year < 1972) y4--; - ay = datetime->year - 1971 - 4 * y4; + ay = datetime->year - 1972 - 4 * y4; ret += y4 * SECPER4YEARS; ret += ay * SECPERYEAR; From 34c59654519cc13b25b39b8add54e757526e5bed Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:04:04 +0200 Subject: [PATCH 106/315] Support version 33 including symlinks --- grub-core/fs/zfs/zfs.c | 149 ++++++++++++++++++++++++++++++++++--- include/grub/zfs/sa_impl.h | 3 + include/grub/zfs/zfs.h | 2 +- 3 files changed, 141 insertions(+), 13 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index e248a1114..454fc4a4a 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1839,19 +1839,18 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) + if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE + && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *sym_value; - grub_size_t avail_in_dnode; grub_size_t sym_sz; int free_symval = 0; char *oldpath = path, *oldpathbuf = path_buf; sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys)); - avail_in_dnode = (char *) (&dnode_path->dn + 1) - sym_value; sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian); - if (sym_sz > avail_in_dnode - 8) + if (dnode_path->dn.dn.dn_flags & 1) { grub_size_t block; grub_size_t blksz; @@ -1905,6 +1904,62 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } + if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dnode_path->dn.dn.dn_bonuslen != 0) + { + sahdrp = DN_BONUS (&dnode_path->dn.dn); + } + else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dnode_path->dn.dn.dn_spill; + + err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); + if (err) + return err; + } + else + { + return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + + if (((grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_TYPE_OFFSET), dnode_path->dn.endian) >> 12) & 0xf) == 0xa) + { + char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET; + grub_size_t sym_sz = + grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), dnode_path->dn.endian); + char *oldpath = path, *oldpathbuf = path_buf; + path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + return grub_errno; + } + grub_memcpy (path, sym_value, sym_sz); + path [sym_sz] = 0; + grub_memcpy (path + grub_strlen (path), oldpath, + grub_strlen (oldpath) + 1); + + grub_free (oldpathbuf); + if (path[0] != '/') + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + else while (dnode_path != root) + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + } + } } if (!err) @@ -2666,12 +2721,14 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) } hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET); + file->size = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); } - else + else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) { file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian); } + else + return grub_error (GRUB_ERR_BAD_FS, "bad bonus type"); file->data = data; file->offset = 0; @@ -2830,8 +2887,39 @@ fill_fs_info (struct grub_dirhook_info *info, return; } - info->mtimeset = 1; - info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + if (dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dn.dn.dn_bonuslen != 0) + { + sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn); + } + else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dn.dn.dn_spill; + + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) + return; + } + else + { + grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + return; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) + { + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + } return; } @@ -2855,10 +2943,47 @@ grub_zfs_dir (grub_device_t device, const char *path, grub_memset (&info, 0, sizeof (info)); dnode_get (&(data->mdn), val, 0, &dn, data); - info.mtimeset = 1; - info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); - info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); - grub_dprintf ("zfs", "type=%d, name=%s\n", + + if (dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dn.dn.dn_bonuslen != 0) + { + sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); + } + else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dn.dn.dn_spill; + + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) + { + grub_print_error (); + return 0; + } + } + else + { + grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + grub_print_error (); + return 0; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) + { + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], + dn.endian); + } + info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); + grub_dprintf ("zfs", "type=%d, name=%s\n", (int)dn.dn.dn_type, (char *)name); return hook (name, &info); } diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h index a2b728d37..0845d1290 100644 --- a/include/grub/zfs/sa_impl.h +++ b/include/grub/zfs/sa_impl.h @@ -29,6 +29,9 @@ typedef struct sa_hdr_phys { } sa_hdr_phys_t; #define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) +#define SA_TYPE_OFFSET 0x0 #define SA_SIZE_OFFSET 0x8 +#define SA_MTIME_OFFSET 0x38 +#define SA_SYMLINK_OFFSET 0xa0 #endif /* _SYS_SA_IMPL_H */ diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 374068d06..d7029903a 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -28,7 +28,7 @@ /* * On-disk version number. */ -#define SPA_VERSION 31ULL +#define SPA_VERSION 33ULL /* * The following are configuration names used in the nvlist describing a pool's From 8563e2a6707a0a8bed9b36734799a7a3a62e5103 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:36:10 +0200 Subject: [PATCH 107/315] Small multidevice fix --- grub-core/fs/zfs/zfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 454fc4a4a..b4deba5c0 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -495,9 +495,9 @@ fill_vdev_info_real (struct grub_zfs_data *data, fill->vdev_phys_sector = insert->vdev_phys_sector; fill->current_uberblock = insert->current_uberblock; fill->original = insert->original; + if (!data->device_original) + data->device_original = fill; } - if (!data->device_original) - data->device_original = fill; return GRUB_ERR_NONE; } From 52a050751b79c3480f8019a789e255df2b546e70 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:52:54 +0200 Subject: [PATCH 108/315] * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. --- ChangeLog | 4 ++++ grub-core/fs/nilfs2.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1abd5daa2..7d2bdd80d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-26 Vladimir Serbinenko + + * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. + 2011-10-26 Vladimir Serbinenko ZFS multi-device and version 33 support. diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 62cf167c7..5986002ef 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -1117,7 +1117,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid) { *uuid = grub_xasprintf - ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x", + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", data->sblock.s_uuid[0], data->sblock.s_uuid[1], data->sblock.s_uuid[2], data->sblock.s_uuid[3], data->sblock.s_uuid[4], data->sblock.s_uuid[5], From 8e32442e804edaf471ffc4156541e089ce2d5374 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:55:07 +0200 Subject: [PATCH 109/315] * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support -l argument. Add newline at the end if printing. (GRUB_MOD_INIT): Document -l. --- ChangeLog | 6 ++++++ grub-core/commands/xnu_uuid.c | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d2bdd80d..d2ed9f2ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-26 Vladimir Serbinenko + + * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support + -l argument. Add newline at the end if printing. + (GRUB_MOD_INIT): Document -l. + 2011-10-26 Vladimir Serbinenko * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. diff --git a/grub-core/commands/xnu_uuid.c b/grub-core/commands/xnu_uuid.c index f618b4ec0..3d152a6d6 100644 --- a/grub-core/commands/xnu_uuid.c +++ b/grub-core/commands/xnu_uuid.c @@ -51,10 +51,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]; char *ptr; grub_uint8_t ctx[GRUB_MD_MD5->contextsize]; + int low = 0; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required"); + if (argc > 1 && grub_strcmp (args[0], "-l") == 0) + { + low = 1; + argc--; + args++; + } + serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16)); GRUB_MD_MD5->init (&ctx); @@ -75,10 +83,11 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11], (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13], (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]); - for (ptr = uuid_string; *ptr; ptr++) - *ptr = grub_toupper (*ptr); + if (!low) + for (ptr = uuid_string; *ptr; ptr++) + *ptr = grub_toupper (*ptr); if (argc == 1) - grub_printf ("%s", uuid_string); + grub_printf ("%s\n", uuid_string); if (argc > 1) grub_env_set (args[1], uuid_string); @@ -91,9 +100,10 @@ static grub_command_t cmd; GRUB_MOD_INIT (xnu_uuid) { cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid, - N_("GRUBUUID [VARNAME]"), + N_("[-l] GRUBUUID [VARNAME]"), N_("Transform 64-bit UUID to format " - "suitable for XNU.")); + "suitable for XNU. If -l is given keep " + "it lowercase as done by blkid.")); } GRUB_MOD_FINI (xnu_uuid) From 3be82e10a9fb1a1d7a7486827f362cb9036f489c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:58:32 +0200 Subject: [PATCH 110/315] fstest xnu_uuid subcommand. * grub-core/commands/xnu_uuid.c (libgrubkrn): Add grub-core/commands/xnu_uuid.c. * util/grub-fstest.c (CMD_XNU_UUID): New enum value. (fstest): Handle xnu_uuid. (options): Document xnu_uuid. (argp_parser): Parse xnu_uuid. --- ChangeLog | 11 +++++++++++ Makefile.util.def | 1 + util/grub-fstest.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d2ed9f2ef..9068bd856 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-10-26 Vladimir Serbinenko + + fstest xnu_uuid subcommand. + + * grub-core/commands/xnu_uuid.c (libgrubkrn): Add + grub-core/commands/xnu_uuid.c. + * util/grub-fstest.c (CMD_XNU_UUID): New enum value. + (fstest): Handle xnu_uuid. + (options): Document xnu_uuid. + (argp_parser): Parse xnu_uuid. + 2011-10-26 Vladimir Serbinenko * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support diff --git a/Makefile.util.def b/Makefile.util.def index e1040c24f..1b66ab961 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -43,6 +43,7 @@ library = { common_nodist = grub_script.tab.h; common = grub-core/commands/blocklist.c; + common = grub-core/commands/xnu_uuid.c; common = grub-core/commands/testload.c; common = grub-core/commands/ls.c; common = grub-core/disk/dmraid_nvidia.c; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index b6ed2ef0c..60889d05e 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -63,7 +63,8 @@ enum { CMD_CRC, CMD_BLOCKLIST, CMD_TESTLOAD, - CMD_ZFSINFO + CMD_ZFSINFO, + CMD_XNU_UUID }; #define BUF_SIZE 32256 @@ -378,6 +379,27 @@ fstest (int n, char **args) case CMD_TESTLOAD: execute_command ("testload", n, args); grub_printf ("\n"); + case CMD_XNU_UUID: + { + grub_device_t dev; + grub_fs_t fs; + char *uuid = 0; + char *argv[3] = { "-l", NULL, NULL}; + dev = grub_device_open (n ? args[0] : 0); + if (!dev) + grub_util_error (grub_errmsg); + fs = grub_fs_probe (dev); + if (!fs) + grub_util_error (grub_errmsg); + if (!fs->uuid) + grub_util_error ("couldn't retrieve UUID"); + if (fs->uuid (dev, &uuid)) + grub_util_error (grub_errmsg); + if (!uuid) + grub_util_error ("couldn't retrieve UUID"); + argv[1] = uuid; + execute_command ("xnu_uuid", 2, argv); + } } for (i = 0; i < num_disks; i++) @@ -406,6 +428,7 @@ static struct argp_option options[] = { {N_("hex FILE"), 0, 0 , OPTION_DOC, N_("Hex dump FILE."), 1}, {N_("crc FILE"), 0, 0 , OPTION_DOC, N_("Get crc32 checksum of FILE."), 1}, {N_("blocklist FILE"), 0, 0, OPTION_DOC, N_("Display blocklist of FILE."), 1}, + {N_("xnu_uuid"), 0, 0, OPTION_DOC, N_("Compute XNU UUID of the device."), 1}, {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"skip", 's', "N", 0, N_("Skip N bytes from output file."), 2}, @@ -558,6 +581,11 @@ argp_parser (int key, char *arg, struct argp_state *state) cmd = CMD_TESTLOAD; nparm = 1; } + else if (grub_strcmp (arg, "xnu_uuid") == 0) + { + cmd = CMD_XNU_UUID; + nparm = 0; + } else { fprintf (stderr, _("Invalid command %s.\n"), arg); From 91c3fdde0deb12db912ca9a3e0436babae634f1e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:59:45 +0200 Subject: [PATCH 111/315] * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. --- ChangeLog | 4 ++ grub-core/fs/ntfs.c | 124 ++++++++++++++++++-------------- grub-core/fs/ntfscomp.c | 53 +++++++------- include/grub/ntfs.h | 156 +++++++++++++++++++++------------------- 4 files changed, 181 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9068bd856..f8b6a78dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-26 Vladimir Serbinenko + + * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. + 2011-10-26 Vladimir Serbinenko fstest xnu_uuid subcommand. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 6b8455c34..bff760e71 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#define grub_fshelp_node grub_ntfs_file + #include #include #include @@ -30,7 +32,19 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; -ntfscomp_func_t grub_ntfscomp_func; +#define grub_fshelp_node grub_ntfs_file + +#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) + +#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) +#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) +#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) + +#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) +#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) +#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) + +grub_ntfscomp_func_t grub_ntfscomp_func; static grub_err_t fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) @@ -87,7 +101,7 @@ static void init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) { at->mft = mft; - at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0; + at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; at->attr_nxt = mft->buf + u16at (mft->buf, 0x14); at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; } @@ -103,7 +117,7 @@ free_attr (struct grub_ntfs_attr *at) static char * find_attr (struct grub_ntfs_attr *at, unsigned char attr) { - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) { retry: while (at->attr_nxt < at->attr_end) @@ -114,7 +128,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) { char *new_pos; - if (at->flags & AF_MMFT) + if (at->flags & GRUB_NTFS_AF_MMFT) { if ((grub_disk_read (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0, @@ -160,7 +174,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) while ((unsigned char) *at->attr_cur != 0xFF) { at->attr_nxt += u16at (at->attr_cur, 4); - if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST) + if ((unsigned char) *at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) at->attr_end = at->attr_cur; if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) return at->attr_cur; @@ -170,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) { char *pa; - at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR); + at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (at->emft_buf == NULL) return NULL; @@ -199,7 +213,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) at->attr_nxt = at->attr_end + u16at (pa, 0x14); at->attr_end = at->attr_end + u32at (pa, 4); } - at->flags |= AF_ALST; + at->flags |= GRUB_NTFS_AF_ALST; while (at->attr_nxt < at->attr_end) { if (((unsigned char) *at->attr_nxt == attr) || (attr == 0)) @@ -209,9 +223,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) if (at->attr_nxt >= at->attr_end) return NULL; - if ((at->flags & AF_MMFT) && (attr == AT_DATA)) + if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) { - at->flags |= AF_GPOS; + at->flags |= GRUB_NTFS_AF_GPOS; at->attr_cur = at->attr_nxt; pa = at->attr_cur; v32at (pa, 0x10) = at->mft->data->mft_start; @@ -223,13 +237,13 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) break; if (read_attr (at, pa + 0x10, - u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR), - at->mft->data->mft_size << BLK_SHR, 0, 0)) + u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), + at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) return NULL; pa += u16at (pa, 4); } at->attr_nxt = at->attr_cur; - at->flags &= ~AF_GPOS; + at->flags &= ~GRUB_NTFS_AF_GPOS; } goto retry; } @@ -245,13 +259,13 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, init_attr (at, mft); if ((pa = find_attr (at, attr)) == NULL) return NULL; - if ((at->flags & AF_ALST) == 0) + if ((at->flags & GRUB_NTFS_AF_ALST) == 0) { while (1) { if ((pa = find_attr (at, attr)) == NULL) break; - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) return pa; } grub_errno = GRUB_ERR_NONE; @@ -296,7 +310,7 @@ retry: c2 = ((unsigned char) (*run) >> 4); if (!c1) { - if ((ctx->attr) && (ctx->attr->flags & AF_ALST)) + if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) { void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector, unsigned offset, @@ -325,9 +339,9 @@ retry: run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */ ctx->curr_lcn += val; if (val == 0) - ctx->flags |= RF_BLNK; + ctx->flags |= GRUB_NTFS_RF_BLNK; else - ctx->flags &= ~RF_BLNK; + ctx->flags &= ~GRUB_NTFS_RF_BLNK; ctx->cur_run = run; return 0; } @@ -345,7 +359,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) return ctx->curr_lcn; } else - return (ctx->flags & RF_BLNK) ? 0 : (block - + return (ctx->flags & GRUB_NTFS_RF_BLNK) ? 0 : (block - ctx->curr_vcn + ctx->curr_lcn); } @@ -376,24 +390,24 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return 0; } - if (u16at (pa, 0xC) & FLAG_COMPRESSED) - ctx->flags |= RF_COMP; + if (u16at (pa, 0xC) & GRUB_NTFS_FLAG_COMPRESSED) + ctx->flags |= GRUB_NTFS_RF_COMP; else - ctx->flags &= ~RF_COMP; + ctx->flags &= ~GRUB_NTFS_RF_COMP; ctx->cur_run = pa + u16at (pa, 0x20); - if (ctx->flags & RF_COMP) + if (ctx->flags & GRUB_NTFS_RF_COMP) { if (!cached) return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); if (at->sbuf) { - if ((ofs & (~(COM_LEN - 1))) == at->save_pos) + if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == at->save_pos) { grub_disk_addr_t n; - n = COM_LEN - (ofs - at->save_pos); + n = GRUB_NTFS_COM_LEN - (ofs - at->save_pos); if (n > len) n = len; @@ -408,17 +422,17 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, } else { - at->sbuf = grub_malloc (COM_LEN); + at->sbuf = grub_malloc (GRUB_NTFS_COM_LEN); if (at->sbuf == NULL) return grub_errno; at->save_pos = 1; } - vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc); + vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC / ctx->comp.spc); ctx->target_vcn &= ~0xF; } else - vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0); + vcn = ctx->target_vcn = grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, 0); ctx->next_vcn = u32at (pa, 0x10); ctx->curr_lcn = 0; @@ -428,12 +442,12 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return grub_errno; } - if (at->flags & AF_GPOS) + if (at->flags & GRUB_NTFS_AF_GPOS) { grub_disk_addr_t st0, st1; grub_uint64_t m; - grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m); + grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, &m); st0 = (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m; @@ -450,7 +464,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return 0; } - if (!(ctx->flags & RF_COMP)) + if (!(ctx->flags & GRUB_NTFS_RF_COMP)) { unsigned int pow; @@ -481,12 +495,12 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, save_cur = at->attr_cur; at->attr_nxt = at->attr_cur; attr = (unsigned char) *at->attr_nxt; - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) { char *pa; grub_disk_addr_t vcn; - vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0); + vcn = grub_divmod64 (ofs, at->mft->data->spc << GRUB_NTFS_BLK_SHR, 0); pa = at->attr_nxt + u16at (at->attr_nxt, 4); while (pa < at->attr_end) { @@ -513,8 +527,8 @@ static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) { if (read_attr - (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR), - data->mft_size << BLK_SHR, 0, 0)) + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), + data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); return fixup (data, buf, data->mft_size, "FILE"); } @@ -526,7 +540,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) mft->inode_read = 1; - mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (mft->buf == NULL) return grub_errno; @@ -541,7 +555,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) { char *pa; - pa = locate_attr (&mft->attr, mft, AT_DATA); + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA); if (pa == NULL) return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno); @@ -550,7 +564,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) else mft->size = u64at (pa, 0x30); - if ((mft->attr.flags & AF_ALST) == 0) + if ((mft->attr.flags & GRUB_NTFS_AF_ALST) == 0) mft->attr.attr_end = 0; /* Don't jump to attribute list */ } else @@ -603,7 +617,7 @@ list_file (struct grub_ntfs_file *diro, char *pos, } type = - (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : + (u32at (pos, 0x48) & GRUB_NTFS_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG; fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); @@ -668,7 +682,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, init_attr (at, mft); while (1) { - if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL) + if ((cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT)) == NULL) { grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); goto done; @@ -694,7 +708,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, bitmap_len = 0; free_attr (at); init_attr (at, mft); - while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL) + while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) { int ofs; @@ -735,7 +749,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, } free_attr (at); - cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION); + cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION); while (cur_pos != NULL) { /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */ @@ -743,7 +757,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, (u32at (cur_pos, 0x40) == 0x490024) && (u32at (cur_pos, 0x44) == 0x300033)) break; - cur_pos = find_attr (at, AT_INDEX_ALLOCATION); + cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION); } if ((!cur_pos) && (bitmap)) @@ -756,7 +770,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, { grub_disk_addr_t v, i; - indx = grub_malloc (mft->data->idx_size << BLK_SHR); + indx = grub_malloc (mft->data->idx_size << GRUB_NTFS_BLK_SHR); if (indx == NULL) goto done; @@ -766,8 +780,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, if (*bitmap & v) { if ((read_attr - (at, indx, i * (mft->data->idx_size << BLK_SHR), - (mft->data->idx_size << BLK_SHR), 0, 0)) + (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0)) || (fixup (mft->data, indx, mft->data->idx_size, "INDX"))) goto done; ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook); @@ -814,32 +828,32 @@ grub_ntfs_mount (grub_disk_t disk) goto fail; data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector); - data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR); + data->spc = bpb.sectors_per_cluster * (data->blocksize >> GRUB_NTFS_BLK_SHR); if (bpb.clusters_per_mft > 0) data->mft_size = data->spc * bpb.clusters_per_mft; else - data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR); + data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); if (bpb.clusters_per_index > 0) data->idx_size = data->spc * bpb.clusters_per_index; else - data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR); + data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc; - if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX)) + if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX)) goto fail; data->mmft.data = data; data->cmft.data = data; - data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR); + data->mmft.buf = grub_malloc (data->mft_size << GRUB_NTFS_BLK_SHR); if (!data->mmft.buf) goto fail; if (grub_disk_read - (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf)) + (disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf)) goto fail; data->uuid = grub_le_to_cpu64 (bpb.num_serial); @@ -847,10 +861,10 @@ grub_ntfs_mount (grub_disk_t disk) if (fixup (data, data->mmft.buf, data->mft_size, "FILE")) goto fail; - if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA)) + if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA)) goto fail; - if (init_file (&data->cmft, FILE_ROOT)) + if (init_file (&data->cmft, GRUB_NTFS_FILE_ROOT)) goto fail; return data; @@ -1030,7 +1044,7 @@ grub_ntfs_label (grub_device_t device, char **label) if (!mft->inode_read) { - mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (mft->buf == NULL) goto fail; @@ -1039,7 +1053,7 @@ grub_ntfs_label (grub_device_t device, char **label) } init_attr (&mft->attr, mft); - pa = find_attr (&mft->attr, AT_VOLUME_NAME); + pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) { char *buf; diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c index d2893cb99..890faa3bf 100644 --- a/grub-core/fs/ntfscomp.c +++ b/grub-core/fs/ntfscomp.c @@ -21,7 +21,6 @@ #include #include #include -#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -35,7 +34,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) (cc->disk, (cc->comp_table[cc->comp_head][1] - (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0, - cc->spc << BLK_SHR, cc->cbuf)) + cc->spc << GRUB_NTFS_BLK_SHR, cc->cbuf)) return grub_errno; cc->cbuf_vcn++; if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0])) @@ -47,7 +46,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) static grub_err_t decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) { - if (cc->cbuf_ofs >= (cc->spc << BLK_SHR)) + if (cc->cbuf_ofs >= (cc->spc << GRUB_NTFS_BLK_SHR)) { if (decomp_nextvcn (cc)) return grub_errno; @@ -87,7 +86,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) bits = copied = tag = 0; while (cnt > 0) { - if (copied > COM_LEN) + if (copied > GRUB_NTFS_COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "compression block too large"); @@ -150,7 +149,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) } else { - if (cnt != COM_LEN) + if (cnt != GRUB_NTFS_COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "invalid compression block size"); } @@ -160,7 +159,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) { int n; - n = (cc->spc << BLK_SHR) - cc->cbuf_ofs; + n = (cc->spc << GRUB_NTFS_BLK_SHR) - cc->cbuf_ofs; if (n > cnt) n = cnt; if ((dest) && (n)) @@ -179,7 +178,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) static grub_err_t read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) { - int cpb = COM_SEC / ctx->comp.spc; + int cpb = GRUB_NTFS_COM_SEC / ctx->comp.spc; while (num) { @@ -192,7 +191,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) return grub_error (GRUB_ERR_BAD_FS, "invalid compression block"); ctx->comp.comp_head = ctx->comp.comp_tail = 0; ctx->comp.cbuf_vcn = ctx->target_vcn; - ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR); + ctx->comp.cbuf_ofs = (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (ctx->target_vcn >= ctx->next_vcn) { if (grub_ntfs_read_run_list (ctx)) @@ -200,7 +199,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) } while (ctx->target_vcn + 16 > ctx->next_vcn) { - if (ctx->flags & RF_BLNK) + if (ctx->flags & GRUB_NTFS_RF_BLNK) break; ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn; ctx->comp.comp_table[ctx->comp.comp_tail][1] = @@ -216,15 +215,15 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) nn = num; num -= nn; - if (ctx->flags & RF_BLNK) + if (ctx->flags & GRUB_NTFS_RF_BLNK) { ctx->target_vcn += nn * cpb; if (ctx->comp.comp_tail == 0) { if (buf) { - grub_memset (buf, 0, nn * COM_LEN); - buf += nn * COM_LEN; + grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN); + buf += nn * GRUB_NTFS_COM_LEN; } } else @@ -234,7 +233,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) if (decomp_block (&ctx->comp, buf)) return grub_errno; if (buf) - buf += COM_LEN; + buf += GRUB_NTFS_COM_LEN; nn--; } } @@ -259,9 +258,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) (ctx->comp.comp_table[ctx->comp.comp_head][1] - (ctx->comp.comp_table[ctx->comp.comp_head][0] - ctx->target_vcn)) * ctx->comp.spc, 0, - tt * (ctx->comp.spc << BLK_SHR), buf)) + tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) return grub_errno; - buf += tt * (ctx->comp.spc << BLK_SHR); + buf += tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); } nn -= tt; if (ctx->target_vcn >= @@ -276,9 +275,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) (ctx->comp.disk, (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc, 0, - nn * (ctx->comp.spc << BLK_SHR), buf)) + nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) return grub_errno; - buf += nn * (ctx->comp.spc << BLK_SHR); + buf += nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); } ctx->target_vcn += nn; } @@ -294,7 +293,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, grub_err_t ret; ctx->comp.comp_head = ctx->comp.comp_tail = 0; - ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR); + ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << GRUB_NTFS_BLK_SHR); if (!ctx->comp.cbuf) return 0; @@ -304,17 +303,17 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, if ((vcn > ctx->target_vcn) && (read_block - (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC))) + (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / GRUB_NTFS_COM_SEC))) { ret = grub_errno; goto quit; } - if (ofs % COM_LEN) + if (ofs % GRUB_NTFS_COM_LEN) { grub_uint32_t t, n, o; - t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; @@ -323,8 +322,8 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, at->save_pos = t; - o = ofs % COM_LEN; - n = COM_LEN - o; + o = ofs % GRUB_NTFS_COM_LEN; + n = GRUB_NTFS_COM_LEN - o; if (n > len) n = len; grub_memcpy (dest, &at->sbuf[o], n); @@ -334,19 +333,19 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, len -= n; } - if (read_block (ctx, dest, len / COM_LEN)) + if (read_block (ctx, dest, len / GRUB_NTFS_COM_LEN)) { ret = grub_errno; goto quit; } - dest += (len / COM_LEN) * COM_LEN; - len = len % COM_LEN; + dest += (len / GRUB_NTFS_COM_LEN) * GRUB_NTFS_COM_LEN; + len = len % GRUB_NTFS_COM_LEN; if (len) { grub_uint32_t t; - t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index e220fecf4..cf90ce110 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -20,79 +20,87 @@ #ifndef GRUB_NTFS_H #define GRUB_NTFS_H 1 -#define FILE_MFT 0 -#define FILE_MFTMIRR 1 -#define FILE_LOGFILE 2 -#define FILE_VOLUME 3 -#define FILE_ATTRDEF 4 -#define FILE_ROOT 5 -#define FILE_BITMAP 6 -#define FILE_BOOT 7 -#define FILE_BADCLUS 8 -#define FILE_QUOTA 9 -#define FILE_UPCASE 10 +enum + { + GRUB_NTFS_FILE_MFT = 0, + GRUB_NTFS_FILE_MFTMIRR = 1, + GRUB_NTFS_FILE_LOGFILE = 2, + GRUB_NTFS_FILE_VOLUME = 3, + GRUB_NTFS_FILE_ATTRDEF = 4, + GRUB_NTFS_FILE_ROOT = 5, + GRUB_NTFS_FILE_BITMAP = 6, + GRUB_NTFS_FILE_BOOT = 7, + GRUB_NTFS_FILE_BADCLUS = 8, + GRUB_NTFS_FILE_QUOTA = 9, + GRUB_NTFS_FILE_UPCASE = 10, + }; -#define AT_STANDARD_INFORMATION 0x10 -#define AT_ATTRIBUTE_LIST 0x20 -#define AT_FILENAME 0x30 -#define AT_OBJECT_ID 0x40 -#define AT_SECURITY_DESCRIPTOR 0x50 -#define AT_VOLUME_NAME 0x60 -#define AT_VOLUME_INFORMATION 0x70 -#define AT_DATA 0x80 -#define AT_INDEX_ROOT 0x90 -#define AT_INDEX_ALLOCATION 0xA0 -#define AT_BITMAP 0xB0 -#define AT_SYMLINK 0xC0 -#define AT_EA_INFORMATION 0xD0 -#define AT_EA 0xE0 +enum + { + GRUB_NTFS_AT_STANDARD_INFORMATION = 0x10, + GRUB_NTFS_AT_ATTRIBUTE_LIST = 0x20, + GRUB_NTFS_AT_FILENAME = 0x30, + GRUB_NTFS_AT_OBJECT_ID = 0x40, + GRUB_NTFS_AT_SECURITY_DESCRIPTOR = 0x50, + GRUB_NTFS_AT_VOLUME_NAME = 0x60, + GRUB_NTFS_AT_VOLUME_INFORMATION = 0x70, + GRUB_NTFS_AT_DATA = 0x80, + GRUB_NTFS_AT_INDEX_ROOT = 0x90, + GRUB_NTFS_AT_INDEX_ALLOCATION = 0xA0, + GRUB_NTFS_AT_BITMAP = 0xB0, + GRUB_NTFS_AT_SYMLINK = 0xC0, + GRUB_NTFS_AT_EA_INFORMATION = 0xD0, + GRUB_NTFS_AT_EA = 0xE0, + }; -#define ATTR_READ_ONLY 0x1 -#define ATTR_HIDDEN 0x2 -#define ATTR_SYSTEM 0x4 -#define ATTR_ARCHIVE 0x20 -#define ATTR_DEVICE 0x40 -#define ATTR_NORMAL 0x80 -#define ATTR_TEMPORARY 0x100 -#define ATTR_SPARSE 0x200 -#define ATTR_REPARSE 0x400 -#define ATTR_COMPRESSED 0x800 -#define ATTR_OFFLINE 0x1000 -#define ATTR_NOT_INDEXED 0x2000 -#define ATTR_ENCRYPTED 0x4000 -#define ATTR_DIRECTORY 0x10000000 -#define ATTR_INDEX_VIEW 0x20000000 +enum + { + GRUB_NTFS_ATTR_READ_ONLY = 0x1, + GRUB_NTFS_ATTR_HIDDEN = 0x2, + GRUB_NTFS_ATTR_SYSTEM = 0x4, + GRUB_NTFS_ATTR_ARCHIVE = 0x20, + GRUB_NTFS_ATTR_DEVICE = 0x40, + GRUB_NTFS_ATTR_NORMAL = 0x80, + GRUB_NTFS_ATTR_TEMPORARY = 0x100, + GRUB_NTFS_ATTR_SPARSE = 0x200, + GRUB_NTFS_ATTR_REPARSE = 0x400, + GRUB_NTFS_ATTR_COMPRESSED = 0x800, + GRUB_NTFS_ATTR_OFFLINE = 0x1000, + GRUB_NTFS_ATTR_NOT_INDEXED = 0x2000, + GRUB_NTFS_ATTR_ENCRYPTED = 0x4000, + GRUB_NTFS_ATTR_DIRECTORY = 0x10000000, + GRUB_NTFS_ATTR_INDEX_VIEW = 0x20000000 + }; -#define FLAG_COMPRESSED 1 -#define FLAG_ENCRYPTED 0x4000 -#define FLAG_SPARSE 0x8000 +enum + { + GRUB_NTFS_FLAG_COMPRESSED = 1, + GRUB_NTFS_FLAG_ENCRYPTED = 0x4000, + GRUB_NTFS_FLAG_SPARSE = 0x8000 + }; -#define BLK_SHR GRUB_DISK_SECTOR_BITS +#define GRUB_NTFS_BLK_SHR GRUB_DISK_SECTOR_BITS -#define MAX_MFT (1024 >> BLK_SHR) -#define MAX_IDX (16384 >> BLK_SHR) +#define GRUB_NTFS_MAX_MFT (1024 >> GRUB_NTFS_BLK_SHR) +#define GRUB_NTFS_MAX_IDX (16384 >> GRUB_NTFS_BLK_SHR) -#define COM_LEN 4096 -#define COM_LOG_LEN 12 -#define COM_SEC (COM_LEN >> BLK_SHR) +#define GRUB_NTFS_COM_LEN 4096 +#define GRUB_NTFS_COM_LOG_LEN 12 +#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR) -#define AF_ALST 1 -#define AF_MMFT 2 -#define AF_GPOS 4 +enum + { + GRUB_NTFS_AF_ALST = 1, + GRUB_NTFS_AF_MMFT = 2, + GRUB_NTFS_AF_GPOS = 4, + }; -#define RF_COMP 1 -#define RF_CBLK 2 -#define RF_BLNK 4 - -#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) - -#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) -#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) -#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) - -#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) -#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) -#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) +enum + { + GRUB_NTFS_RF_COMP = 1, + GRUB_NTFS_RF_CBLK = 2, + GRUB_NTFS_RF_BLNK = 4 + }; struct grub_ntfs_bpb { @@ -120,8 +128,6 @@ struct grub_ntfs_bpb grub_uint32_t checksum; } __attribute__ ((packed)); -#define grub_ntfs_file grub_fshelp_node - struct grub_ntfs_attr { int flags; @@ -132,7 +138,7 @@ struct grub_ntfs_attr struct grub_ntfs_file *mft; }; -struct grub_fshelp_node +struct grub_ntfs_file { struct grub_ntfs_data *data; char *buf; @@ -174,13 +180,15 @@ struct grub_ntfs_rlst struct grub_ntfs_comp comp; }; -typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest, - grub_uint32_t ofs, grub_uint32_t len, - struct grub_ntfs_rlst * ctx, - grub_uint32_t vcn); +typedef grub_err_t (*grub_ntfscomp_func_t) (struct grub_ntfs_attr * at, + char *dest, + grub_uint32_t ofs, + grub_uint32_t len, + struct grub_ntfs_rlst * ctx, + grub_uint32_t vcn); -extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func); +extern grub_ntfscomp_func_t grub_ntfscomp_func; -grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx); +grub_err_t grub_ntfs_read_run_list (struct grub_ntfs_rlst *ctx); #endif /* ! GRUB_NTFS_H */ From 5773fb64104944b2af0a988183861e88b5579fe6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 03:04:27 +0200 Subject: [PATCH 112/315] Support NTFS reparse points. * grub-core/fs/ntfs.c (list_file): Set symlink type when appropriate. (symlink_descriptor): New struct. (grub_ntfs_read_symlink): New function. (grub_ntfs_iterate_dir): Use grub_ntfs_read_symlink. (grub_ntfs_open): Likewise. --- ChangeLog | 10 ++++ grub-core/fs/ntfs.c | 110 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8b6a78dc..8c3c50434 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-26 Vladimir Serbinenko + + Support NTFS reparse points. + + * grub-core/fs/ntfs.c (list_file): Set symlink type when appropriate. + (symlink_descriptor): New struct. + (grub_ntfs_read_symlink): New function. + (grub_ntfs_iterate_dir): Use grub_ntfs_read_symlink. + (grub_ntfs_open): Likewise. + 2011-10-26 Vladimir Serbinenko * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index bff760e71..13de52cd8 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -609,6 +609,7 @@ list_file (struct grub_ntfs_file *diro, char *pos, { enum grub_fshelp_filetype type; struct grub_ntfs_file *fdiro; + grub_uint32_t attr; if (u16at (pos, 4)) { @@ -616,9 +617,13 @@ list_file (struct grub_ntfs_file *diro, char *pos, return 0; } - type = - (u32at (pos, 0x48) & GRUB_NTFS_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : - GRUB_FSHELP_REG; + attr = u32at (pos, 0x48); + if (attr & GRUB_NTFS_ATTR_REPARSE) + type = GRUB_FSHELP_SYMLINK; + else if (attr & GRUB_NTFS_ATTR_DIRECTORY) + type = GRUB_FSHELP_DIR; + else + type = GRUB_FSHELP_REG; fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); if (!fdiro) @@ -653,6 +658,101 @@ list_file (struct grub_ntfs_file *diro, char *pos, return 0; } +struct symlink_descriptor +{ + grub_uint32_t type; + grub_uint32_t total_len; + grub_uint16_t off1; + grub_uint16_t len1; + grub_uint16_t off2; + grub_uint16_t len2; +} __attribute__ ((packed)); + +static char * +grub_ntfs_read_symlink (grub_fshelp_node_t node) +{ + struct grub_ntfs_file *mft; + struct symlink_descriptor symdesc; + grub_err_t err; + grub_uint16_t *buf16; + char *buf, *end; + grub_size_t len; + grub_size_t i; + char *pa; + grub_size_t off; + + mft = (struct grub_ntfs_file *) node; + + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (mft->buf == NULL) + return NULL; + + if (read_mft (mft->data, mft->buf, mft->ino)) + return NULL; + + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK); + if (pa == NULL) + { + grub_error (GRUB_ERR_BAD_FS, "no $SYMLINK in MFT 0x%X", mft->ino); + return NULL; + } + + err = read_attr (&mft->attr, (char *) &symdesc, 0, + sizeof (struct symlink_descriptor), 1, 0); + if (err) + return NULL; + + switch (grub_cpu_to_le32 (symdesc.type)) + { + case 0xa000000c: + off = sizeof (struct symlink_descriptor) + 4 + grub_cpu_to_le32 (symdesc.off1); + len = grub_cpu_to_le32 (symdesc.len1); + break; + case 0xa0000003: + off = sizeof (struct symlink_descriptor) + grub_cpu_to_le32 (symdesc.off1); + len = grub_cpu_to_le32 (symdesc.len1); + break; + default: + grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", + grub_cpu_to_le32 (symdesc.type)); + grub_printf ("%d\n", __LINE__); + return NULL; + } + + buf16 = grub_malloc (len); + if (!buf16) + return NULL; + + err = read_attr (&mft->attr, (char *) buf16, off, len, 1, 0); + if (err) + return NULL; + + buf = grub_malloc (len * 2 + 1); + if (!buf) + { + grub_free (buf16); + return NULL; + } + + for (i = 0; i < len / 2; i++) + { + buf16[i] = grub_le_to_cpu16 (buf16[i]); + if (buf16[i] == '\\') + buf16[i] = '/'; + } + + end = (char *) grub_utf16_to_utf8 ((grub_uint8_t *) buf, buf16, len / 2); + *end = '\0'; + /* Split the sequence to avoid GCC thinking that this is a trigraph. */ + if (grub_memcmp (buf, "/?" "?/", 4) == 0 && buf[5] == ':' && buf[6] == '/' + && grub_isalpha (buf[4])) + { + grub_memmove (buf, buf + 6, end - buf + 1 - 6); + end -= 6; + } + return buf; +} + static int grub_ntfs_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -915,7 +1015,7 @@ grub_ntfs_dir (grub_device_t device, const char *path, goto fail; grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, - 0, GRUB_FSHELP_DIR); + grub_ntfs_read_symlink, GRUB_FSHELP_DIR); if (grub_errno) goto fail; @@ -953,7 +1053,7 @@ grub_ntfs_open (grub_file_t file, const char *name) goto fail; grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir, - 0, GRUB_FSHELP_REG); + grub_ntfs_read_symlink, GRUB_FSHELP_REG); if (grub_errno) goto fail; From f8d82408d9f13aa960e2f73317cabb0a66f207e7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 20:55:09 +0200 Subject: [PATCH 113/315] * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. (zfs_unmount): Fix memory leak. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8c3c50434..980452003 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-27 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. + (zfs_unmount): Fix memory leak. + 2011-10-26 Vladimir Serbinenko Support NTFS reparse points. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3253457c7..9bd68222a 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -865,7 +865,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, } case DEVICE_MIRROR: { - grub_err_t err; + grub_err_t err = GRUB_ERR_NONE; unsigned i; if (desc->n_children <= 0) return grub_error (GRUB_ERR_BAD_FS, @@ -2498,6 +2498,7 @@ zfs_unmount (struct grub_zfs_data *data) unsigned i; for (i = 0; i < data->n_devices_attached; i++) unmount_device (&data->devices_attached[i]); + grub_free (data->devices_attached); grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); From 5b1ae25f068e405374a8f5b063b1f8a4260274a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 20:58:52 +0200 Subject: [PATCH 114/315] Support BFS (befs) UUID. * grub-core/fs/afs.c (grub_afs_inode): Make small_data zero-size. (grub_afs_small_data_element_header): New struct. (grub_afs_read_inode): Read complete inode. Fix ino type while on it. (grub_afs_read_attribute) [MODE_BFS]: New function. (grub_afs_iterate_dir): Allocate for complete inode. (grub_afs_mount): Likewise. (grub_afs_uuid) [MODE_BFS]: New function. (grub_afs_fs) [MODE_BFS]: Add .uuid. --- ChangeLog | 13 ++++ grub-core/fs/afs.c | 163 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 162 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 980452003..cfb00531a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-10-27 Vladimir Serbinenko + + Support BFS (befs) UUID. + + * grub-core/fs/afs.c (grub_afs_inode): Make small_data zero-size. + (grub_afs_small_data_element_header): New struct. + (grub_afs_read_inode): Read complete inode. Fix ino type while on it. + (grub_afs_read_attribute) [MODE_BFS]: New function. + (grub_afs_iterate_dir): Allocate for complete inode. + (grub_afs_mount): Likewise. + (grub_afs_uuid) [MODE_BFS]: New function. + (grub_afs_fs) [MODE_BFS]: Add .uuid. + 2011-10-27 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index b64ebb52c..ea7a9e9ed 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -210,7 +210,14 @@ struct grub_afs_inode grub_uint32_t unused; struct grub_afs_datastream stream; grub_uint32_t pad[4]; - grub_uint32_t small_data[1]; + grub_uint8_t small_data[0]; +} __attribute__ ((packed)); + +struct grub_afs_small_data_element_header +{ + grub_uint32_t type; + grub_uint16_t name_len; + grub_uint16_t value_len; } __attribute__ ((packed)); struct grub_fshelp_node @@ -229,6 +236,19 @@ struct grub_afs_data static grub_dl_t my_mod; +static int +grub_afs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)); +static grub_ssize_t +grub_afs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + grub_off_t pos, grub_size_t len, char *buf); + + static grub_afs_off_t grub_afs_run_to_num (struct grub_afs_sblock *sb, struct grub_afs_blockrun *run) @@ -239,15 +259,87 @@ grub_afs_run_to_num (struct grub_afs_sblock *sb, static grub_err_t grub_afs_read_inode (struct grub_afs_data *data, - grub_uint32_t ino, struct grub_afs_inode *inode) + grub_uint64_t ino, struct grub_afs_inode *inode) { return grub_disk_read (data->disk, ino * (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS), - 0, sizeof (struct grub_afs_inode), - inode); + 0, data->sblock.block_size, inode); } +#ifdef MODE_BFS +static grub_ssize_t +grub_afs_read_attribute (grub_fshelp_node_t node, + const char *name, char *buf, grub_size_t len) +{ + grub_ssize_t read = -1; + auto int NESTED_FUNC_ATTR hook (const char *filename, + enum grub_fshelp_filetype filetype + __attribute__ ((unused)), + grub_fshelp_node_t attr_node); + + int NESTED_FUNC_ATTR hook (const char *filename, + enum grub_fshelp_filetype filetype + __attribute__ ((unused)), + grub_fshelp_node_t attr_node) + { + if (grub_strcmp (filename, name) == 0) + { + read = grub_afs_read_file (attr_node, 0, 0, len, buf); + return 1; + } + return 0; + } + grub_uint8_t *ptr = node->inode.small_data; + grub_uint8_t *end = ((grub_uint8_t *) &node->inode + + node->data->sblock.block_size); + + while (ptr + sizeof (struct grub_afs_small_data_element_header) < end) + { + struct grub_afs_small_data_element_header *el; + char *el_name; + grub_uint8_t *data; + el = (struct grub_afs_small_data_element_header *) ptr; + if (el->name_len == 0) + break; + el_name = (char *) (el + 1); + data = (grub_uint8_t *) el_name + grub_afs_to_cpu16 (el->name_len) + 3; + ptr = data + grub_afs_to_cpu16 (el->value_len) + 1; + if (grub_memcmp (name, el_name, grub_afs_to_cpu16 (el->name_len)) == 0 + && name[el->name_len] == 0) + { + grub_size_t copy; + copy = len; + if (grub_afs_to_cpu16 (el->value_len) > copy) + copy = grub_afs_to_cpu16 (el->value_len); + grub_memcpy (buf, data, copy); + return copy; + } + } + + { + struct grub_fshelp_node *fdiro; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node) + + node->data->sblock.block_size + - sizeof (struct grub_afs_inode)); + if (! fdiro) + return -1; + + fdiro->data = node->data; + if (grub_afs_read_inode (node->data, + grub_afs_run_to_num (&node->data->sblock, + &node->inode.attrib_dir), + &fdiro->inode)) + return -1; + + grub_afs_iterate_dir (fdiro, hook); + } + + return read; +} +#endif + static grub_disk_addr_t grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { @@ -424,7 +516,9 @@ grub_afs_iterate_dir (grub_fshelp_node_t dir, struct grub_fshelp_node *fdiro; int mode, type; - fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + fdiro = grub_malloc (sizeof (struct grub_fshelp_node) + + dir->data->sblock.block_size + - sizeof (struct grub_afs_inode)); if (! fdiro) return 0; @@ -521,18 +615,31 @@ static struct grub_afs_data * grub_afs_mount (grub_disk_t disk) { struct grub_afs_data *data = 0; - - data = grub_malloc (sizeof (struct grub_afs_data)); - if (!data) - return 0; + struct grub_afs_sblock sb; + grub_err_t err; /* Read the superblock. */ - if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, - sizeof (struct grub_afs_sblock), &data->sblock)) - goto fail; + err = grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, + sizeof (struct grub_afs_sblock), &sb); + if (err) + { + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); + return NULL; + } - if (! grub_afs_validate_sblock (&data->sblock)) - goto fail; + if (! grub_afs_validate_sblock (&sb)) + { + grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); + return NULL; + } + + data = grub_malloc (sizeof (struct grub_afs_data) + sb.block_size + - sizeof (struct grub_afs_inode)); + if (!data) + return NULL; + + data->sblock = sb; data->diropen.data = data; data->inode = &data->diropen.inode; @@ -681,6 +788,31 @@ grub_afs_label (grub_device_t device, char **label) return grub_errno; } +#ifdef MODE_BFS +static grub_err_t +grub_afs_uuid (grub_device_t device, char **uuid) +{ + struct grub_afs_data *data; + grub_disk_t disk = device->disk; + grub_uint64_t vid; + grub_ssize_t read; + + *uuid = NULL; + + data = grub_afs_mount (disk); + if (!data) + return grub_errno; + read = grub_afs_read_attribute (&data->diropen, "be:volume_id", + (char *) &vid, + sizeof (vid)); + if (read == sizeof (vid)) + *uuid = grub_xasprintf ("%" PRIxGRUB_UINT64_T, grub_afs_to_cpu64 (vid)); + + grub_free (data); + + return grub_errno; +} +#endif static struct grub_fs grub_afs_fs = { .name = GRUB_AFS_FSNAME, @@ -689,6 +821,9 @@ static struct grub_fs grub_afs_fs = { .read = grub_afs_read, .close = grub_afs_close, .label = grub_afs_label, +#ifdef MODE_BFS + .uuid = grub_afs_uuid, +#endif .next = 0 }; From 6563f63dfd8eb3b3e5db20b774ca3fadb3aac4b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 15:52:15 +0200 Subject: [PATCH 115/315] * grub-core/disk/raid.c (scan_devices): Check partition. * grub-core/disk/lvm.c (do_lvm_scan): Likewise. --- ChangeLog | 5 +++++ grub-core/disk/lvm.c | 7 ++++++- grub-core/disk/raid.c | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfb00531a..d2fc4ba84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-28 Vladimir Serbinenko + + * grub-core/disk/raid.c (scan_devices): Check partition. + * grub-core/disk/lvm.c (do_lvm_scan): Likewise. + 2011-10-27 Vladimir Serbinenko Support BFS (befs) UUID. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 7c19f08de..7c65db4ab 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -153,7 +154,11 @@ do_lvm_scan (const char *scan_for) for (vg = vg_list; vg; vg = vg->next) for (pv = vg->pvs; pv; pv = pv->next) if (pv->disk && pv->disk->id == disk->id - && pv->disk->dev->id == disk->dev->id) + && pv->disk->dev->id == disk->dev->id + && grub_partition_get_start (pv->disk->partition) + == grub_partition_get_start (disk->partition) + && grub_partition_get_len (pv->disk->partition) + == grub_partition_get_len (disk->partition)) { grub_disk_close (disk); return 0; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 5d8326daf..07249eabc 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include #endif @@ -119,7 +120,11 @@ scan_devices (const char *arname) struct grub_raid_member *m; for (m = arr->members; m < arr->members + arr->nr_devs; m++) if (m->device && m->device->id == disk->id - && m->device->dev->id == m->device->dev->id) + && m->device->dev->id == m->device->dev->id + && grub_partition_get_start (m->device->partition) + == grub_partition_get_start (disk->partition) + && grub_partition_get_len (m->device->partition) + == grub_partition_get_len (disk->partition)) { grub_disk_close (disk); return 0; From ad03fe768e8b47cb51612dfa3545fd1a892bbe7f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 15:59:47 +0200 Subject: [PATCH 116/315] Correct befs block counting logic. * grub-core/fs/afs.c (GRUB_AFS_BLOCKS_PER_DI_RUN): Replaced with... (GRUB_AFS_LOG_BLOCKS_PER_DI_RUN): ... this. (GRUB_AFS_BLOCKRUN_LOG_SIZE): New definition. (grub_afs_read_inode): Use block_shift. (RANGE_SHIFT): New definition. (grub_afs_read_block): Account for RANGE_SHIFT, emit errors on unexpected conditions, use shifts and appropriate types. (GRUB_MOD_INIT): Check the value of GRUB_AFS_BLOCKRUN_LOG_SIZE. --- ChangeLog | 13 +++++++++ grub-core/fs/afs.c | 67 ++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2fc4ba84..64ae05ef4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-10-28 Vladimir Serbinenko + + Correct befs block counting logic. + + * grub-core/fs/afs.c (GRUB_AFS_BLOCKS_PER_DI_RUN): Replaced with... + (GRUB_AFS_LOG_BLOCKS_PER_DI_RUN): ... this. + (GRUB_AFS_BLOCKRUN_LOG_SIZE): New definition. + (grub_afs_read_inode): Use block_shift. + (RANGE_SHIFT): New definition. + (grub_afs_read_block): Account for RANGE_SHIFT, emit errors on + unexpected conditions, use shifts and appropriate types. + (GRUB_MOD_INIT): Check the value of GRUB_AFS_BLOCKRUN_LOG_SIZE. + 2011-10-28 Vladimir Serbinenko * grub-core/disk/raid.c (scan_devices): Check partition. diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index ea7a9e9ed..9a646ac88 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #endif #define GRUB_AFS_DIRECT_BLOCK_COUNT 12 -#define GRUB_AFS_BLOCKS_PER_DI_RUN 4 +#define GRUB_AFS_LOG_BLOCKS_PER_DI_RUN 2 #ifdef MODE_BFS #define GRUB_AFS_SBLOCK_SECTOR 1 @@ -103,6 +103,7 @@ typedef grub_uint64_t grub_afs_off_t; typedef grub_uint64_t grub_afs_bigtime; typedef grub_uint64_t grub_afs_bvalue_t; +#define GRUB_AFS_BLOCKRUN_LOG_SIZE 3 struct grub_afs_blockrun { grub_uint32_t group; @@ -262,8 +263,7 @@ grub_afs_read_inode (struct grub_afs_data *data, grub_uint64_t ino, struct grub_afs_inode *inode) { return grub_disk_read (data->disk, - ino * - (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS), + ino << (data->sblock.block_shift - GRUB_DISK_SECTOR_BITS), 0, data->sblock.block_size, inode); } @@ -340,13 +340,19 @@ grub_afs_read_attribute (grub_fshelp_node_t node, } #endif +#ifdef MODE_BFS +#define RANGE_SHIFT sb->block_shift +#else +#define RANGE_SHIFT 0 +#endif + static grub_disk_addr_t grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { struct grub_afs_sblock *sb = &node->data->sblock; struct grub_afs_datastream *ds = &node->inode.stream; - if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range)) + if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_direct_range)) { int i; @@ -356,21 +362,24 @@ grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock; fileblock -= grub_afs_to_cpu16 (ds->direct[i].len); } + grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); + return 0; } - else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range)) + else if ((fileblock << RANGE_SHIFT) + < grub_afs_to_cpu64 (ds->max_indirect_range)) { - int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); struct grub_afs_blockrun indir[ptrs_per_blk]; grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect); int i; - fileblock -= grub_afs_to_cpu64 (ds->max_direct_range); + fileblock -= grub_afs_to_cpu64 (ds->max_direct_range) >> RANGE_SHIFT; for (i = 0; i < ds->indirect.len; i++, blk++) { - int j; + grub_size_t j; if (grub_disk_read (node->data->disk, - blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS), + blk << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; @@ -383,43 +392,47 @@ grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) fileblock -= grub_afs_to_cpu16 (indir[j].len); } } + grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); + return 0; } - else + else if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_double_indirect_range)) { - int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); struct grub_afs_blockrun indir[ptrs_per_blk]; - + grub_disk_addr_t off, dptr, dblk, idptr, idblk; /* ([idblk][idptr]) ([dblk][dptr]) [blk] */ - int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range); - int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN; - int dblk_size = dptr_size * ptrs_per_blk; - int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN; - int idblk_size = idptr_size * ptrs_per_blk; + fileblock -= grub_afs_to_cpu64 (ds->max_indirect_range) >> RANGE_SHIFT; - int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN; - int dptr = (cur_pos / dptr_size) % ptrs_per_blk; - int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN; - int idptr = (cur_pos / idptr_size) % ptrs_per_blk; - int idblk = (cur_pos / idblk_size); + /* Divisions and modulo fixed number are optimised by compiler. */ + off = fileblock & ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); + dptr = fileblock >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; + dblk = dptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); + dptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); + idptr = dblk >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; + dblk &= ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); + idblk = idptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); + idptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); if (grub_disk_read (node->data->disk, (grub_afs_run_to_num (sb, &ds->double_indirect) - + idblk) * - (sb->block_size >> GRUB_DISK_SECTOR_BITS), + + idblk) << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) * - (sb->block_size >> GRUB_DISK_SECTOR_BITS), + (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) + << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; return grub_afs_run_to_num (sb, &indir[dptr]) + off; } + + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "triple-indirect on " GRUB_AFS_FSNAME " isn't supported"); return 0; } @@ -837,6 +850,8 @@ GRUB_MOD_INIT (afs_be) GRUB_MOD_INIT (afs) #endif { + COMPILE_TIME_ASSERT ((1 << GRUB_AFS_BLOCKRUN_LOG_SIZE) + == sizeof (struct grub_afs_blockrun)); grub_fs_register (&grub_afs_fs); my_mod = mod; } From ed9ba06dd011b1e66bcb757f4cb5e4a4db54ecbc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:05:16 +0200 Subject: [PATCH 117/315] Use shifts in squash4. * grub-core/fs/squash4.c (grub_squash_data): New field log2_blksz. (squash_mount): Check block size and take logarithm. (direct_read): Use shifts. --- ChangeLog | 8 ++++++++ grub-core/fs/squash4.c | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 64ae05ef4..6d0cfde93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in squash4. + + * grub-core/fs/squash4.c (grub_squash_data): New field log2_blksz. + (squash_mount): Check block size and take logarithm. + (direct_read): Use shifts. + 2011-10-28 Vladimir Serbinenko Correct befs block counting logic. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index d45732c16..a3832b6be 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -173,6 +173,7 @@ struct grub_squash_data struct grub_squash_super sb; struct grub_squash_cache_inode ino; grub_uint64_t fragments; + int log2_blksz; }; struct grub_fshelp_node @@ -267,7 +268,10 @@ squash_mount (grub_disk_t disk) grub_error (GRUB_ERR_BAD_FS, "not a squash4"); if (err) return NULL; - if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC) + if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC + || grub_le_to_cpu32 (sb.block_size) == 0 + || ((grub_le_to_cpu32 (sb.block_size) - 1) + & grub_le_to_cpu32 (sb.block_size))) { grub_error (GRUB_ERR_BAD_FS, "not squash4"); return NULL; @@ -290,6 +294,10 @@ squash_mount (grub_disk_t disk) data->disk = disk; data->fragments = grub_le_to_cpu64 (frag); + for (data->log2_blksz = 0; + (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sb.block_size); + data->log2_blksz++); + return data; } @@ -528,10 +536,9 @@ direct_read (struct grub_squash_data *data, block_offset = ((char *) &ino->ino.file.block_size - (char *) &ino->ino); } - total_blocks = grub_divmod64 (total_size - + grub_le_to_cpu32 (data->sb.block_size) - 1, - grub_le_to_cpu32 (data->sb.block_size), - 0); + total_blocks = ((total_size + + grub_le_to_cpu32 (data->sb.block_size) - 1) + >> data->log2_blksz); ino->block_sizes = grub_malloc (total_blocks * sizeof (ino->block_sizes[0])); ino->cumulated_block_sizes = grub_malloc (total_blocks @@ -565,7 +572,7 @@ direct_read (struct grub_squash_data *data, if (a == 0) a = sizeof (struct grub_squash_super); - i = grub_divmod64 (off, grub_le_to_cpu32 (data->sb.block_size), 0); + i = off >> data->log2_blksz; cumulated_uncompressed_size = grub_le_to_cpu32 (data->sb.block_size) * (grub_disk_addr_t) i; while (cumulated_uncompressed_size < off + len) From 564dd58c2acf88c5f2a046eae52feb62332dde61 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:09:20 +0200 Subject: [PATCH 118/315] Use shifts in minix filesystem. * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use log_block_size. (GRUB_MINIX_ZONE2SECT): Likewise. (grub_minix_data): Replace block_size with log_block_size. (grub_minix_read_file): Use shifts. (grub_minix_mount): Check block size and take a logarithm. --- ChangeLog | 10 ++++++++++ grub-core/fs/minix.c | 32 +++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d0cfde93..f73d431d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in minix filesystem. + + * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use log_block_size. + (GRUB_MINIX_ZONE2SECT): Likewise. + (grub_minix_data): Replace block_size with log_block_size. + (grub_minix_read_file): Use shifts. + (grub_minix_mount): Check block size and take a logarithm. + 2011-10-28 Vladimir Serbinenko Use shifts in squash4. diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 43785b657..401883e36 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -76,11 +76,11 @@ typedef grub_uint16_t grub_minix_ino_t; #define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ + grub_le_to_cpu16 (data->sblock.log2_zone_size)) #endif -#define GRUB_MINIX_ZONESZ (data->block_size \ - << grub_le_to_cpu16 (data->sblock.log2_zone_size)) +#define GRUB_MINIX_ZONESZ (1 << (data->log_block_size \ + + grub_le_to_cpu16 (data->sblock.log2_zone_size))) #ifdef MODE_MINIX3 -#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * (data->block_size / GRUB_DISK_SECTOR_SIZE)) +#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << (data->log_block_size - GRUB_DISK_SECTOR_BITS)) #else #define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ) #endif @@ -159,7 +159,7 @@ struct grub_minix_data int linknest; grub_disk_t disk; int filename_size; - grub_size_t block_size; + grub_size_t log_block_size; }; static grub_dl_t my_mod; @@ -251,14 +251,15 @@ grub_minix_read_file (struct grub_minix_data *data, if (len + pos > GRUB_MINIX_INODE_SIZE (data)) len = GRUB_MINIX_INODE_SIZE (data) - pos; - blockcnt = grub_divmod64 ((len + pos + data->block_size - 1), - data->block_size, 0); - posblock = grub_divmod64 (pos, data->block_size, &blockoff); + blockcnt = ((len + pos + (1 << data->log_block_size) - 1) + >> data->log_block_size); + posblock = pos >> data->log_block_size; + blockoff = pos & ((1 << data->log_block_size) - 1); for (i = posblock; i < blockcnt; i++) { grub_disk_addr_t blknr; - grub_uint64_t blockend = data->block_size; + grub_uint64_t blockend = 1 << data->log_block_size; grub_off_t skipfirst = 0; blknr = grub_minix_get_file_block (data, i); @@ -268,10 +269,10 @@ grub_minix_read_file (struct grub_minix_data *data, /* Last block. */ if (i == blockcnt - 1) { - grub_divmod64 (len + pos, data->block_size, &blockend); + blockend = (len + pos) & ((1 << data->log_block_size) - 1); if (!blockend) - blockend = data->block_size; + blockend = 1 << data->log_block_size; } /* First block. */ @@ -289,7 +290,7 @@ grub_minix_read_file (struct grub_minix_data *data, if (grub_errno) return -1; - buf += data->block_size - skipfirst; + buf += (1 << data->log_block_size) - skipfirst; } return len; @@ -479,9 +480,14 @@ grub_minix_mount (grub_disk_t disk) data->disk = disk; data->linknest = 0; #ifdef MODE_MINIX3 - data->block_size = grub_le_to_cpu16 (data->sblock.block_size); + if ((grub_le_to_cpu16 (data->sblock.block_size) + & (grub_le_to_cpu16 (data->sblock.block_size) - 1)) + || grub_le_to_cpu16 (data->sblock.block_size) == 0) + goto fail; + for (data->log_block_size = 0; (1 << data->log_block_size) + < grub_le_to_cpu16 (data->sblock.block_size); data->log_block_size++); #else - data->block_size = 1024U; + data->log_block_size = 10; #endif return data; From e551115a26167205995f315881881ddf0db7b722 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:21:18 +0200 Subject: [PATCH 119/315] Use shifts in nilfs2. * grub-core/fs/nilfs2.c (LOG_INODE_SIZE): New definition. (LOG_NILFS_DAT_ENTRY_SIZE): Likewise. (grub_nilfs2_palloc_entries_per_group): Replace with ... (grub_nilfs2_log_palloc_entries_per_group): ... this. (grub_nilfs2_palloc_group): Use shifts and bitmasks. (grub_nilfs2_entries_per_block): Replaced with ... (grub_nilfs2_log_entries_per_block_log): ... this. (grub_nilfs2_blocks_per_group): Replaced with ... (grub_nilfs2_blocks_per_group_log): ... this. (grub_nilfs2_blocks_per_desc_block): Replaced with ... (grub_nilfs2_blocks_per_desc_block_log): ... this. (grub_nilfs2_palloc_desc_block_offset): Replaced with ... (grub_nilfs2_palloc_desc_block_offset_log): ... this. (grub_nilfs2_palloc_entry_offset): Replaced ... (grub_nilfs2_palloc_entry_offset_log): ... this. Use shifts. (grub_nilfs2_dat_translate): Use shifts. (grub_nilfs2_read_inode): Likewise. (GRUB_MOD_INIT): Ensure that logs are correct. --- ChangeLog | 23 ++++++++++++ grub-core/fs/nilfs2.c | 87 +++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index f73d431d2..979b5335a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in nilfs2. + + * grub-core/fs/nilfs2.c (LOG_INODE_SIZE): New definition. + (LOG_NILFS_DAT_ENTRY_SIZE): Likewise. + (grub_nilfs2_palloc_entries_per_group): Replace with ... + (grub_nilfs2_log_palloc_entries_per_group): ... this. + (grub_nilfs2_palloc_group): Use shifts and bitmasks. + (grub_nilfs2_entries_per_block): Replaced with ... + (grub_nilfs2_log_entries_per_block_log): ... this. + (grub_nilfs2_blocks_per_group): Replaced with ... + (grub_nilfs2_blocks_per_group_log): ... this. + (grub_nilfs2_blocks_per_desc_block): Replaced with ... + (grub_nilfs2_blocks_per_desc_block_log): ... this. + (grub_nilfs2_palloc_desc_block_offset): Replaced with ... + (grub_nilfs2_palloc_desc_block_offset_log): ... this. + (grub_nilfs2_palloc_entry_offset): Replaced ... + (grub_nilfs2_palloc_entry_offset_log): ... this. Use shifts. + (grub_nilfs2_dat_translate): Use shifts. + (grub_nilfs2_read_inode): Likewise. + (GRUB_MOD_INIT): Ensure that logs are correct. + 2011-10-28 Vladimir Serbinenko Use shifts in minix filesystem. diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 5986002ef..a8bbe9566 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -58,6 +58,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); in 512 block size */ #define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3) +#define LOG_INODE_SIZE 7 struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -214,6 +215,7 @@ struct grub_nilfs2_palloc_group_desc grub_uint32_t pg_nfrees; }; +#define LOG_NILFS_DAT_ENTRY_SIZE 5 struct grub_nilfs2_dat_entry { grub_uint64_t de_blocknr; @@ -296,17 +298,17 @@ static grub_dl_t my_mod; static inline unsigned long -grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) +grub_nilfs2_log_palloc_entries_per_group (struct grub_nilfs2_data *data) { - return 1UL << (LOG2_BLOCK_SIZE (data) + 3); + return LOG2_BLOCK_SIZE (data) + 3; } static inline grub_uint64_t grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, grub_uint64_t nr, grub_uint64_t * offset) { - return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), - offset); + *offset = nr & ((1 << grub_nilfs2_log_palloc_entries_per_group (data)) - 1); + return nr >> grub_nilfs2_log_palloc_entries_per_group (data); } static inline grub_uint32_t @@ -317,55 +319,58 @@ grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) } static inline grub_uint32_t -grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_log_entries_per_block_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { - return NILFS2_BLOCK_SIZE (data) / entry_size; + return LOG2_BLOCK_SIZE (data) - log_entry_size; } static inline grub_uint32_t -grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_blocks_per_group_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { - return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data), - grub_nilfs2_entries_per_block (data, - entry_size)) + 1; + return (1 << (grub_nilfs2_log_palloc_entries_per_group (data) + - grub_nilfs2_log_entries_per_block_log (data, + log_entry_size))) + 1; } static inline grub_uint32_t -grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { return grub_nilfs2_palloc_groups_per_desc_block (data) * - grub_nilfs2_blocks_per_group (data, entry_size) + 1; + grub_nilfs2_blocks_per_group_log (data, log_entry_size) + 1; } static inline grub_uint32_t -grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data, - unsigned long group, - unsigned long entry_size) +grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long log_entry_size) { grub_uint32_t desc_block = group / grub_nilfs2_palloc_groups_per_desc_block (data); - return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size); + return desc_block * grub_nilfs2_blocks_per_desc_block_log (data, + log_entry_size); } static inline grub_uint32_t grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, unsigned long group, - unsigned long entry_size) + unsigned long log_entry_size) { unsigned long desc_offset = group % grub_nilfs2_palloc_groups_per_desc_block (data); - return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 + - desc_offset * grub_nilfs2_blocks_per_group (data, entry_size); + return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size) + + 1 + + desc_offset * grub_nilfs2_blocks_per_group_log (data, log_entry_size); } static inline grub_uint32_t -grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, - grub_uint64_t nr, unsigned long entry_size) +grub_nilfs2_palloc_entry_offset_log (struct grub_nilfs2_data *data, + grub_uint64_t nr, + unsigned long log_entry_size) { unsigned long group; grub_uint64_t group_offset; @@ -373,10 +378,9 @@ grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, group = grub_nilfs2_palloc_group (data, nr, &group_offset); return grub_nilfs2_palloc_bitmap_block_offset (data, group, - entry_size) + 1 + - grub_divmod64 (group_offset, grub_nilfs2_entries_per_block (data, - entry_size), - NULL); + 1 << log_entry_size) + 1 + + (group_offset >> grub_nilfs2_log_entries_per_block_log (data, + log_entry_size)); } @@ -582,12 +586,11 @@ grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) grub_uint64_t blockno, offset; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - blockno = grub_nilfs2_palloc_entry_offset (data, key, - sizeof (struct - grub_nilfs2_dat_entry)); + blockno = grub_nilfs2_palloc_entry_offset_log (data, key, + LOG_NILFS_DAT_ENTRY_SIZE); - grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry), - NILFS2_BLOCK_SIZE (data), &offset); + offset = ((key * sizeof (struct grub_nilfs2_dat_entry)) + & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0); if (pptr == (grub_uint64_t) - 1) @@ -652,8 +655,8 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, sizeof(struct grub_nilfs2_checkpoint). */ blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) / - sizeof (struct grub_nilfs2_checkpoint), &offset); - + sizeof (struct grub_nilfs2_checkpoint), &offset); + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1); if (pptr == (grub_uint64_t) - 1) { @@ -686,12 +689,11 @@ grub_nilfs2_read_inode (struct grub_nilfs2_data *data, grub_disk_t disk = data->disk; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - blockno = grub_nilfs2_palloc_entry_offset (data, ino, - sizeof (struct - grub_nilfs2_inode)); + blockno = grub_nilfs2_palloc_entry_offset_log (data, ino, + LOG_INODE_SIZE); - grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino, - NILFS2_BLOCK_SIZE (data), &offset); + offset = ((sizeof (struct grub_nilfs2_inode) * ino) + & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1); if (pptr == (grub_uint64_t) - 1) { @@ -1178,6 +1180,11 @@ static struct grub_fs grub_nilfs2_fs = { GRUB_MOD_INIT (nilfs2) { + COMPILE_TIME_ASSERT ((1 << LOG_NILFS_DAT_ENTRY_SIZE) + == sizeof (struct + grub_nilfs2_dat_entry)); + COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE + == sizeof (struct grub_nilfs2_inode)); grub_fs_register (&grub_nilfs2_fs); my_mod = mod; } From c39224b052b2322cc75bca9432fdb29617415c82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:26:17 +0200 Subject: [PATCH 120/315] Prefer rockridge over Joliet. * grub-core/fs/iso9660.c (grub_iso9660_mount): Move rockridge detection to ... (set_rockridge): ... here. (grub_iso9660_mount): Check rockridge on the primary label when discovering. Ignore Joliet if Rockridge is present. --- ChangeLog | 10 +++ grub-core/fs/iso9660.c | 140 ++++++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 979b5335a..deaa6ba68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-28 Vladimir Serbinenko + + Prefer rockridge over Joliet. + + * grub-core/fs/iso9660.c (grub_iso9660_mount): Move rockridge detection + to ... + (set_rockridge): ... here. + (grub_iso9660_mount): Check rockridge on the primary label when + discovering. Ignore Joliet if Rockridge is present. + 2011-10-28 Vladimir Serbinenko Use shifts in nilfs2. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index f3e828b89..a2e731351 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -347,17 +347,14 @@ grub_iso9660_convert_string (grub_uint16_t *us, int len) return p; } -static struct grub_iso9660_data * -grub_iso9660_mount (grub_disk_t disk) +static grub_err_t +set_rockridge (struct grub_iso9660_data *data) { - struct grub_iso9660_data *data = 0; - struct grub_iso9660_dir rootdir; int sua_pos; int sua_size; char *sua; + struct grub_iso9660_dir rootdir; struct grub_iso9660_susp_entry *entry; - struct grub_iso9660_primary_voldesc voldesc; - int block; auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *); @@ -373,6 +370,67 @@ grub_iso9660_mount (grub_disk_t disk) return 0; } + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + if (!sua_size) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (! sua) + return grub_errno; + + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->data[2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, + sua_pos, sua_size, susp_iterate)) + return grub_errno; + } + return GRUB_ERR_NONE; +} + +static struct grub_iso9660_data * +grub_iso9660_mount (grub_disk_t disk) +{ + struct grub_iso9660_data *data = 0; + struct grub_iso9660_primary_voldesc voldesc; + int block; + data = grub_zalloc (sizeof (struct grub_iso9660_data)); if (! data) return 0; @@ -400,9 +458,11 @@ grub_iso9660_mount (grub_disk_t disk) } if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) - copy_voldesc = 1; - else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) && - (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) && + copy_voldesc = 1; + else if (!data->rockridge + && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) + && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) + && ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ @@ -412,66 +472,16 @@ grub_iso9660_mount (grub_disk_t disk) } if (copy_voldesc) - grub_memcpy((char *) &data->voldesc, (char *) &voldesc, - sizeof (struct grub_iso9660_primary_voldesc)); + { + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + if (set_rockridge (data)) + goto fail; + } block++; } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); - /* Read the system use area and test it to see if SUSP is - supported. */ - if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), 0, - sizeof (rootdir), (char *) &rootdir)) - { - grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - goto fail; - } - - sua_pos = (sizeof (rootdir) + rootdir.namelen - + (rootdir.namelen % 2) - 1); - sua_size = rootdir.len - sua_pos; - - if (!sua_size) - return data; - - sua = grub_malloc (sua_size); - if (! sua) - goto fail; - - if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, - sua_size, sua)) - { - grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - goto fail; - } - - entry = (struct grub_iso9660_susp_entry *) sua; - - /* Test if the SUSP protocol is used on this filesystem. */ - if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) - { - struct grub_fshelp_node rootnode; - - rootnode.data = data; - rootnode.alloc_dirents = 0; - rootnode.have_dirents = 1; - rootnode.symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - - /* The 2nd data byte stored how many bytes are skipped every time - to get to the SUA (System Usage Area). */ - data->susp_skip = entry->data[2]; - entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); - - /* Iterate over the entries in the SUA area to detect - extensions. */ - if (grub_iso9660_susp_iterate (&rootnode, - sua_pos, sua_size, susp_iterate)) - goto fail; - } - return data; fail: From faba3d163aa2ef77a38e0aebfc0c873fadfdcb35 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 29 Oct 2011 11:29:34 +0200 Subject: [PATCH 121/315] Remove afs and befs because of copyright problem. * grub-core/fs/afs.c: Removed. * grub-core/fs/afs_be.c: Removed. * grub-core/fs/befs.c: Removed. * grub-core/fs/befs_be.c: Removed. * Makefile.util.def (libgrubkern): Remove afs, afs_be, befs and befs_be. * grub-core/Makefile.core.def (afs): Removed. (afs_be): Likewise. (befs): Likewise. (befs_be): Likewise. --- ChangeLog | 14 + Makefile.util.def | 4 - grub-core/Makefile.core.def | 20 - grub-core/fs/afs.c | 870 ------------------------------------ grub-core/fs/afs_be.c | 2 - grub-core/fs/befs.c | 3 - grub-core/fs/befs_be.c | 4 - 7 files changed, 14 insertions(+), 903 deletions(-) delete mode 100644 grub-core/fs/afs.c delete mode 100644 grub-core/fs/afs_be.c delete mode 100644 grub-core/fs/befs.c delete mode 100644 grub-core/fs/befs_be.c diff --git a/ChangeLog b/ChangeLog index deaa6ba68..892357ff3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-10-29 Vladimir Serbinenko + + Remove afs and befs because of copyright problem. + + * grub-core/fs/afs.c: Removed. + * grub-core/fs/afs_be.c: Removed. + * grub-core/fs/befs.c: Removed. + * grub-core/fs/befs_be.c: Removed. + * Makefile.util.def (libgrubkern): Remove afs, afs_be, befs and befs_be. + * grub-core/Makefile.core.def (afs): Removed. + (afs_be): Likewise. + (befs): Likewise. + (befs_be): Likewise. + 2011-10-28 Vladimir Serbinenko Prefer rockridge over Joliet. diff --git a/Makefile.util.def b/Makefile.util.def index 1b66ab961..bc66a51d4 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,10 +55,6 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; - common = grub-core/fs/afs_be.c; - common = grub-core/fs/afs.c; - common = grub-core/fs/befs_be.c; - common = grub-core/fs/befs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 6d3c31ea6..2d91c3b64 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,26 +970,6 @@ module = { common = fs/affs.c; }; -module = { - name = afs; - common = fs/afs.c; -}; - -module = { - name = afs_be; - common = fs/afs_be.c; -}; - -module = { - name = befs; - common = fs/befs.c; -}; - -module = { - name = befs_be; - common = fs/befs_be.c; -}; - module = { name = btrfs; common = fs/btrfs.c; diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c deleted file mode 100644 index 9a646ac88..000000000 --- a/grub-core/fs/afs.c +++ /dev/null @@ -1,870 +0,0 @@ -/* afs.c - The native AtheOS file-system. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef MODE_BIGENDIAN -#define GRUB_AFS_FSNAME_SUFFIX "_be" -#else -#define GRUB_AFS_FSNAME_SUFFIX "" -#endif - -#ifdef MODE_BFS -#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX -#else -#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX -#endif - -#define GRUB_AFS_DIRECT_BLOCK_COUNT 12 -#define GRUB_AFS_LOG_BLOCKS_PER_DI_RUN 2 - -#ifdef MODE_BFS -#define GRUB_AFS_SBLOCK_SECTOR 1 -#define GRUB_AFS_SBLOCK_MAGIC1 0x42465331 /* BFS1. */ -#else -#define GRUB_AFS_SBLOCK_SECTOR 2 -#define GRUB_AFS_SBLOCK_MAGIC1 0x41465331 /* AFS1. */ -#endif - -#define GRUB_AFS_SBLOCK_MAGIC2 0xdd121031 -#define GRUB_AFS_SBLOCK_MAGIC3 0x15b6830e - -#define GRUB_AFS_INODE_MAGIC 0x64358428 - -#ifdef MODE_BFS -#define GRUB_AFS_BTREE_MAGIC 0x69f6c2e8 -#else -#define GRUB_AFS_BTREE_MAGIC 0x65768995 -#endif - -#define GRUB_AFS_BNODE_SIZE 1024 - -#define GRUB_AFS_S_IFMT 00170000 -#define GRUB_AFS_S_IFLNK 0120000 - -#define GRUB_AFS_S_IFREG 0100000 -#define GRUB_AFS_S_IFDIR 0040000 -#define GRUB_AFS_S_IFIFO 0010000 - -#define GRUB_AFS_NULL_VAL ((grub_afs_bvalue_t)-1) - -#ifdef MODE_BIGENDIAN -#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x) -#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x) -#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x) -#else -#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x) -#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x) -#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x) -#endif - -#ifdef MODE_BFS -#define B_KEY_INDEX_ALIGN 8 -#else -#define B_KEY_INDEX_ALIGN 4 -#endif - -#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \ - ((char *) (node) \ - + ALIGN_UP (sizeof (struct grub_afs_bnode) \ - + node->key_size, \ - B_KEY_INDEX_ALIGN))) - -#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \ - ((char *) B_KEY_INDEX_OFFSET (node) + \ - node->key_count * 2)) - -typedef grub_uint64_t grub_afs_off_t; -typedef grub_uint64_t grub_afs_bigtime; -typedef grub_uint64_t grub_afs_bvalue_t; - -#define GRUB_AFS_BLOCKRUN_LOG_SIZE 3 -struct grub_afs_blockrun -{ - grub_uint32_t group; - grub_uint16_t start; - grub_uint16_t len; -} __attribute__ ((packed)); - -struct grub_afs_datastream -{ - struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT]; - grub_afs_off_t max_direct_range; - struct grub_afs_blockrun indirect; - grub_afs_off_t max_indirect_range; - struct grub_afs_blockrun double_indirect; - grub_afs_off_t max_double_indirect_range; - grub_afs_off_t size; -} __attribute__ ((packed)); - -struct grub_afs_bnode -{ - grub_afs_bvalue_t left; - grub_afs_bvalue_t right; - grub_afs_bvalue_t overflow; -#ifdef MODE_BFS - grub_uint16_t key_count; - grub_uint16_t key_size; -#else - grub_uint32_t key_count; - grub_uint32_t key_size; -#endif - char key_data[0]; -} __attribute__ ((packed)); - -#ifdef MODE_BFS -struct grub_afs_btree -{ - grub_uint32_t magic; - grub_uint32_t unused1; - grub_uint32_t tree_depth; - grub_uint32_t unused2; - grub_afs_bvalue_t root; - grub_uint32_t unused3[4]; -} __attribute__ ((packed)); -#else -struct grub_afs_btree -{ - grub_uint32_t magic; - grub_afs_bvalue_t root; - grub_uint32_t tree_depth; - grub_afs_bvalue_t last_node; - grub_afs_bvalue_t first_free; -} __attribute__ ((packed)); -#endif - -/* Beware that following structure describes AtheFS and if you write code - which uses currently unused fields check it with both AtheFS and BeFS. - */ -struct grub_afs_sblock -{ - char name[32]; - grub_uint32_t magic1; - grub_uint32_t byte_order; - grub_uint32_t block_size; - grub_uint32_t block_shift; - grub_afs_off_t num_blocks; - grub_afs_off_t used_blocks; - grub_uint32_t inode_size; - grub_uint32_t magic2; - grub_uint32_t block_per_group; /* Number of blocks per allocation - group. (Max 65536) */ - grub_uint32_t alloc_group_shift; /* Number of bits to shift a group - number to get a byte address. */ - grub_uint32_t alloc_group_count; - grub_uint32_t flags; - struct grub_afs_blockrun log_block; - grub_afs_off_t log_start; - grub_uint32_t valid_log_blocks; - grub_uint32_t log_size; - grub_uint32_t magic3; - struct grub_afs_blockrun root_dir; /* Root dir inode. */ - struct grub_afs_blockrun deleted_files; /* Directory containing files - scheduled for deletion. */ - struct grub_afs_blockrun index_dir; /* Directory of index files. */ - grub_uint32_t boot_loader_size; - grub_uint32_t pad[7]; -} __attribute__ ((packed)); - -struct grub_afs_inode -{ - grub_uint32_t magic1; - struct grub_afs_blockrun inode_num; - grub_uint32_t uid; - grub_uint32_t gid; - grub_uint32_t mode; - grub_uint32_t flags; -#ifndef MODE_BFS - grub_uint32_t link_count; -#endif - grub_afs_bigtime create_time; - grub_afs_bigtime modified_time; - struct grub_afs_blockrun parent; - struct grub_afs_blockrun attrib_dir; - grub_uint32_t index_type; /* Key data-key only used for index files. */ - grub_uint32_t inode_size; - grub_uint32_t unused; - struct grub_afs_datastream stream; - grub_uint32_t pad[4]; - grub_uint8_t small_data[0]; -} __attribute__ ((packed)); - -struct grub_afs_small_data_element_header -{ - grub_uint32_t type; - grub_uint16_t name_len; - grub_uint16_t value_len; -} __attribute__ ((packed)); - -struct grub_fshelp_node -{ - struct grub_afs_data *data; - struct grub_afs_inode inode; -}; - -struct grub_afs_data -{ - grub_disk_t disk; - struct grub_afs_sblock sblock; - struct grub_afs_inode *inode; - struct grub_fshelp_node diropen; -}; - -static grub_dl_t my_mod; - -static int -grub_afs_iterate_dir (grub_fshelp_node_t dir, - int NESTED_FUNC_ATTR - (*hook) (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node)); -static grub_ssize_t -grub_afs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf); - - -static grub_afs_off_t -grub_afs_run_to_num (struct grub_afs_sblock *sb, - struct grub_afs_blockrun *run) -{ - return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group) - * sb->block_per_group + grub_afs_to_cpu16 (run->start)); -} - -static grub_err_t -grub_afs_read_inode (struct grub_afs_data *data, - grub_uint64_t ino, struct grub_afs_inode *inode) -{ - return grub_disk_read (data->disk, - ino << (data->sblock.block_shift - GRUB_DISK_SECTOR_BITS), - 0, data->sblock.block_size, inode); -} - -#ifdef MODE_BFS -static grub_ssize_t -grub_afs_read_attribute (grub_fshelp_node_t node, - const char *name, char *buf, grub_size_t len) -{ - grub_ssize_t read = -1; - auto int NESTED_FUNC_ATTR hook (const char *filename, - enum grub_fshelp_filetype filetype - __attribute__ ((unused)), - grub_fshelp_node_t attr_node); - - int NESTED_FUNC_ATTR hook (const char *filename, - enum grub_fshelp_filetype filetype - __attribute__ ((unused)), - grub_fshelp_node_t attr_node) - { - if (grub_strcmp (filename, name) == 0) - { - read = grub_afs_read_file (attr_node, 0, 0, len, buf); - return 1; - } - return 0; - } - grub_uint8_t *ptr = node->inode.small_data; - grub_uint8_t *end = ((grub_uint8_t *) &node->inode - + node->data->sblock.block_size); - - while (ptr + sizeof (struct grub_afs_small_data_element_header) < end) - { - struct grub_afs_small_data_element_header *el; - char *el_name; - grub_uint8_t *data; - el = (struct grub_afs_small_data_element_header *) ptr; - if (el->name_len == 0) - break; - el_name = (char *) (el + 1); - data = (grub_uint8_t *) el_name + grub_afs_to_cpu16 (el->name_len) + 3; - ptr = data + grub_afs_to_cpu16 (el->value_len) + 1; - if (grub_memcmp (name, el_name, grub_afs_to_cpu16 (el->name_len)) == 0 - && name[el->name_len] == 0) - { - grub_size_t copy; - copy = len; - if (grub_afs_to_cpu16 (el->value_len) > copy) - copy = grub_afs_to_cpu16 (el->value_len); - grub_memcpy (buf, data, copy); - return copy; - } - } - - { - struct grub_fshelp_node *fdiro; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node) - + node->data->sblock.block_size - - sizeof (struct grub_afs_inode)); - if (! fdiro) - return -1; - - fdiro->data = node->data; - if (grub_afs_read_inode (node->data, - grub_afs_run_to_num (&node->data->sblock, - &node->inode.attrib_dir), - &fdiro->inode)) - return -1; - - grub_afs_iterate_dir (fdiro, hook); - } - - return read; -} -#endif - -#ifdef MODE_BFS -#define RANGE_SHIFT sb->block_shift -#else -#define RANGE_SHIFT 0 -#endif - -static grub_disk_addr_t -grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) -{ - struct grub_afs_sblock *sb = &node->data->sblock; - struct grub_afs_datastream *ds = &node->inode.stream; - - if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_direct_range)) - { - int i; - - for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++) - { - if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len)) - return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock; - fileblock -= grub_afs_to_cpu16 (ds->direct[i].len); - } - grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); - return 0; - } - else if ((fileblock << RANGE_SHIFT) - < grub_afs_to_cpu64 (ds->max_indirect_range)) - { - grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); - struct grub_afs_blockrun indir[ptrs_per_blk]; - grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect); - int i; - - fileblock -= grub_afs_to_cpu64 (ds->max_direct_range) >> RANGE_SHIFT; - for (i = 0; i < ds->indirect.len; i++, blk++) - { - grub_size_t j; - - if (grub_disk_read (node->data->disk, - blk << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - for (j = 0; j < ptrs_per_blk; j++) - { - if (fileblock < grub_afs_to_cpu16 (indir[j].len)) - return grub_afs_run_to_num (sb, &indir[j]) + fileblock; - - fileblock -= grub_afs_to_cpu16 (indir[j].len); - } - } - grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); - return 0; - } - else if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_double_indirect_range)) - { - grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); - struct grub_afs_blockrun indir[ptrs_per_blk]; - grub_disk_addr_t off, dptr, dblk, idptr, idblk; - /* ([idblk][idptr]) ([dblk][dptr]) [blk] */ - - fileblock -= grub_afs_to_cpu64 (ds->max_indirect_range) >> RANGE_SHIFT; - - /* Divisions and modulo fixed number are optimised by compiler. */ - off = fileblock & ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); - dptr = fileblock >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; - dblk = dptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); - dptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); - idptr = dblk >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; - dblk &= ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); - idblk = idptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); - idptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); - - if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &ds->double_indirect) - + idblk) << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) - << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - return grub_afs_run_to_num (sb, &indir[dptr]) + off; - } - - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "triple-indirect on " GRUB_AFS_FSNAME " isn't supported"); - - return 0; -} - -static grub_ssize_t -grub_afs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_afs_read_block, - grub_afs_to_cpu64 (node->inode.stream.size), - node->data->sblock.block_shift - - GRUB_DISK_SECTOR_BITS); -} - -static char * -grub_afs_read_symlink (grub_fshelp_node_t node) -{ - char *ret; - grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size); - - if (size == 0) - { - size = sizeof (node->inode.stream); - ret = grub_zalloc (size + 1); - if (! ret) - return 0; - grub_memcpy (ret, (char *) &(node->inode.stream), - sizeof (node->inode.stream)); - return ret; - } - ret = grub_zalloc (size + 1); - if (! ret) - return 0; - grub_afs_read_file (node, 0, 0, size, ret); - return ret; -} - -static int -grub_afs_iterate_dir (grub_fshelp_node_t dir, - int NESTED_FUNC_ATTR - (*hook) (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node)) -{ - struct grub_afs_btree head; - char node_data [GRUB_AFS_BNODE_SIZE]; - struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data; - int i; - - if ((dir->inode.stream.size == 0) - || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT) - != GRUB_AFS_S_IFDIR)) - return 0; - - grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head); - if (grub_errno) - return 0; - - grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root), - GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - - for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++) - { - grub_afs_bvalue_t blk; - - blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]); - grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - } - - if (node->key_count) - { - grub_uint32_t cur_key = 0; - - while (1) - { - int key_start, key_size; - grub_uint16_t *index; - - index = B_KEY_INDEX_OFFSET (node); - - key_start = (cur_key > 0) - ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0; - key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start; - if (key_size > 0) - { - char filename [key_size + 1]; - struct grub_fshelp_node *fdiro; - int mode, type; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node) - + dir->data->sblock.block_size - - sizeof (struct grub_afs_inode)); - if (! fdiro) - return 0; - - fdiro->data = dir->data; - if (grub_afs_read_inode (dir->data, - grub_afs_to_cpu64 - (B_KEY_VALUE_OFFSET (node) [cur_key]), - &fdiro->inode)) - return 0; - - grub_memcpy (filename, &node->key_data[key_start], key_size); - filename [key_size] = 0; - - mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT); - if (mode == GRUB_AFS_S_IFDIR) - type = GRUB_FSHELP_DIR; - else if (mode == GRUB_AFS_S_IFREG) - type = GRUB_FSHELP_REG; - else if (mode == GRUB_AFS_S_IFLNK) - type = GRUB_FSHELP_SYMLINK; - else - type = GRUB_FSHELP_UNKNOWN; - - if (hook (filename, type, fdiro)) - return 1; - } - - cur_key++; - if (cur_key >= grub_afs_to_cpu32 (node->key_count)) - { - if (node->right == GRUB_AFS_NULL_VAL) - break; - - grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right), - GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - - cur_key = 0; - } - } - } - - return 0; -} - -static int -grub_afs_validate_sblock (struct grub_afs_sblock *sb) -{ - if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1) - { - sb->magic2 = grub_afs_to_cpu32 (sb->magic2); - sb->magic3 = grub_afs_to_cpu32 (sb->magic3); - sb->block_shift = grub_afs_to_cpu32 (sb->block_shift); - sb->block_size = grub_afs_to_cpu32 (sb->block_size); - sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks); - sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks); - sb->inode_size = grub_afs_to_cpu32 (sb->inode_size); - sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count); - sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift); - sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group); - sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count); - sb->log_size = grub_afs_to_cpu32 (sb->log_size); - } - else - return 0; - - if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) || - (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3)) - return 0; - -#ifdef MODE_BFS - sb->block_per_group = 1 << (sb->alloc_group_shift); -#endif - - if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size) - || (sb->used_blocks > sb->num_blocks ) - || (sb->inode_size != sb->block_size) - || (0 == sb->block_size) -#ifndef MODE_BFS - || ((grub_uint32_t) (1 << sb->alloc_group_shift) != - sb->block_per_group * sb->block_size) - || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks) - || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size) - || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size) -#endif - ) - return 0; - - return 1; -} - -static struct grub_afs_data * -grub_afs_mount (grub_disk_t disk) -{ - struct grub_afs_data *data = 0; - struct grub_afs_sblock sb; - grub_err_t err; - - /* Read the superblock. */ - err = grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, - sizeof (struct grub_afs_sblock), &sb); - if (err) - { - if (err == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - return NULL; - } - - if (! grub_afs_validate_sblock (&sb)) - { - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - return NULL; - } - - data = grub_malloc (sizeof (struct grub_afs_data) + sb.block_size - - sizeof (struct grub_afs_inode)); - if (!data) - return NULL; - - data->sblock = sb; - - data->diropen.data = data; - data->inode = &data->diropen.inode; - data->disk = disk; - - if (grub_afs_read_inode (data, - grub_afs_run_to_num (&data->sblock, - &data->sblock.root_dir), - data->inode)) - goto fail; - - return data; - -fail: - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - - grub_free (data); - return 0; -} - -static grub_err_t -grub_afs_open (struct grub_file *file, const char *name) -{ - struct grub_afs_data *data; - struct grub_fshelp_node *fdiro = 0; - - grub_dl_ref (my_mod); - - data = grub_afs_mount (file->device->disk); - if (! data) - goto fail; - - grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir, - grub_afs_read_symlink, GRUB_FSHELP_REG); - if (grub_errno) - goto fail; - - grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode)); - grub_free (fdiro); - - file->size = grub_afs_to_cpu64 (data->inode->stream.size); - file->data = data; - file->offset = 0; - - return 0; - -fail: - grub_free (data); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_ssize_t -grub_afs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_afs_data *data = (struct grub_afs_data *) file->data; - - return grub_afs_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); -} - -static grub_err_t -grub_afs_close (grub_file_t file) -{ - grub_free (file->data); - - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_afs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - struct grub_afs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - auto int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node); - - int NESTED_FUNC_ATTR iterate (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - info.mtimeset = 1; -#ifdef MODE_BFS - info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16; -#else - info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time), - 1000000, 0); -#endif - grub_free (node); - return hook (filename, &info); - } - - grub_dl_ref (my_mod); - - data = grub_afs_mount (device->disk); - if (! data) - goto fail; - - grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir, - grub_afs_read_symlink, GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_afs_iterate_dir (fdiro, iterate); - - if (fdiro != &data->diropen) - grub_free (fdiro); - - fail: - grub_free (data); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_err_t -grub_afs_label (grub_device_t device, char **label) -{ - struct grub_afs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_afs_mount (disk); - if (data) - *label = grub_strndup (data->sblock.name, sizeof (data->sblock.name)); - else - *label = NULL; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; -} - -#ifdef MODE_BFS -static grub_err_t -grub_afs_uuid (grub_device_t device, char **uuid) -{ - struct grub_afs_data *data; - grub_disk_t disk = device->disk; - grub_uint64_t vid; - grub_ssize_t read; - - *uuid = NULL; - - data = grub_afs_mount (disk); - if (!data) - return grub_errno; - read = grub_afs_read_attribute (&data->diropen, "be:volume_id", - (char *) &vid, - sizeof (vid)); - if (read == sizeof (vid)) - *uuid = grub_xasprintf ("%" PRIxGRUB_UINT64_T, grub_afs_to_cpu64 (vid)); - - grub_free (data); - - return grub_errno; -} -#endif - -static struct grub_fs grub_afs_fs = { - .name = GRUB_AFS_FSNAME, - .dir = grub_afs_dir, - .open = grub_afs_open, - .read = grub_afs_read, - .close = grub_afs_close, - .label = grub_afs_label, -#ifdef MODE_BFS - .uuid = grub_afs_uuid, -#endif - .next = 0 -}; - -#if defined (MODE_BIGENDIAN) && defined (MODE_BFS) -GRUB_MOD_INIT (befs_be) -#elif defined (MODE_BFS) -GRUB_MOD_INIT (befs) -#elif defined (MODE_BIGENDIAN) -GRUB_MOD_INIT (afs_be) -#else -GRUB_MOD_INIT (afs) -#endif -{ - COMPILE_TIME_ASSERT ((1 << GRUB_AFS_BLOCKRUN_LOG_SIZE) - == sizeof (struct grub_afs_blockrun)); - grub_fs_register (&grub_afs_fs); - my_mod = mod; -} - -#if defined (MODE_BIGENDIAN) && defined (MODE_BFS) -GRUB_MOD_FINI (befs_be) -#elif defined (MODE_BFS) -GRUB_MOD_FINI (befs) -#elif defined (MODE_BIGENDIAN) -GRUB_MOD_FINI (afs_be) -#else -GRUB_MOD_FINI (afs) -#endif -{ - grub_fs_unregister (&grub_afs_fs); -} diff --git a/grub-core/fs/afs_be.c b/grub-core/fs/afs_be.c deleted file mode 100644 index 1f1f48fbb..000000000 --- a/grub-core/fs/afs_be.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_BIGENDIAN 1 -#include "afs.c" diff --git a/grub-core/fs/befs.c b/grub-core/fs/befs.c deleted file mode 100644 index c54d8e1cc..000000000 --- a/grub-core/fs/befs.c +++ /dev/null @@ -1,3 +0,0 @@ -/* befs.c - The native BeOS/Haiku file-system. */ -#define MODE_BFS 1 -#include "afs.c" diff --git a/grub-core/fs/befs_be.c b/grub-core/fs/befs_be.c deleted file mode 100644 index f6e8179f4..000000000 --- a/grub-core/fs/befs_be.c +++ /dev/null @@ -1,4 +0,0 @@ -/* befs.c - The native BeOS/Haiku file-system. */ -#define MODE_BFS 1 -#define MODE_BIGENDIAN 1 -#include "afs.c" From 61b99bfc2a2229f352f74eb8349f54b832e0064b Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Sun, 30 Oct 2011 11:16:23 +0100 Subject: [PATCH 122/315] * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs and befs_be. --- ChangeLog | 5 +++++ po/POTFILES.in | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 892357ff3..604a427c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Yves Blusseau + + * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs + and befs_be. + 2011-10-29 Vladimir Serbinenko Remove afs and befs because of copyright problem. diff --git a/po/POTFILES.in b/po/POTFILES.in index ebb0aadaa..1c718520b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -127,10 +127,6 @@ ./grub-core/font/font.c ./grub-core/font/font_cmd.c ./grub-core/fs/affs.c -./grub-core/fs/afs_be.c -./grub-core/fs/afs.c -./grub-core/fs/befs_be.c -./grub-core/fs/befs.c ./grub-core/fs/btrfs.c ./grub-core/fs/cpio.c ./grub-core/fs/ext2.c From 42b2a706bf071a47d20af08389d1ea3f917f2691 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:18:22 +0100 Subject: [PATCH 123/315] * util/grub-fstest.c (cmd_cp): Clarify error message. (cmd_cmp): Likewise. --- ChangeLog | 5 +++++ util/grub-fstest.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 604a427c6..d8c4bf764 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Vladimir Serbinenko + + * util/grub-fstest.c (cmd_cp): Clarify error message. + (cmd_cmp): Likewise. + 2011-10-30 Yves Blusseau * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 60889d05e..996d71c3a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -182,7 +182,8 @@ cmd_cp (char *src, char *dest) ff = fopen (dest, "wb"); if (ff == NULL) { - grub_util_error (_("open error")); + grub_util_error (_("OS file %s open error: %s"), dest, + strerror (errno)); return; } read_file (src, cp_hook); @@ -241,7 +242,8 @@ cmd_cmp (char *src, char *dest) ff = fopen (dest, "rb"); if (ff == NULL) { - grub_util_error (_("open error")); + grub_util_error (_("OS file %s open error: %s"), dest, + strerror (errno)); return; } From 5825b3794be953aa1b5e2ec564e38713ca59418f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:25:51 +0100 Subject: [PATCH 124/315] BFS implementation based on the specification. * grub-core/fs/bfs.c: New file. * Makefile.util.def (libgrubmods): Add bfs.c. * grub-core/Makefile.core.def (bfs): New module. --- ChangeLog | 8 + Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/bfs.c | 948 ++++++++++++++++++++++++++++++++++++ 4 files changed, 962 insertions(+) create mode 100644 grub-core/fs/bfs.c diff --git a/ChangeLog b/ChangeLog index d8c4bf764..d8ea7974c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-30 Vladimir Serbinenko + + BFS implementation based on the specification. + + * grub-core/fs/bfs.c: New file. + * Makefile.util.def (libgrubmods): Add bfs.c. + * grub-core/Makefile.core.def (bfs): New module. + 2011-10-30 Vladimir Serbinenko * util/grub-fstest.c (cmd_cp): Clarify error message. diff --git a/Makefile.util.def b/Makefile.util.def index bc66a51d4..053ff4340 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,6 +55,7 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; + common = grub-core/fs/bfs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2d91c3b64..c6127b28f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,6 +970,11 @@ module = { common = fs/affs.c; }; +module = { + name = bfs; + common = fs/bfs.c; +}; + module = { name = btrfs; common = fs/btrfs.c; diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c new file mode 100644 index 000000000..6f6ebf908 --- /dev/null +++ b/grub-core/fs/bfs.c @@ -0,0 +1,948 @@ +/* bfs.c - The Bee File System. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 . + */ +/* + Based on the book "Practical File System Design by Dominic Giampaolo + with corrections and completitions based on Haiku code. +*/ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define grub_bfs_to_cpu16 grub_le_to_cpu16 +#define grub_bfs_to_cpu32 grub_le_to_cpu32 +#define grub_bfs_to_cpu64 grub_le_to_cpu64 + +#define SUPER_BLOCK_MAGIC1 0x42465331 +#define SUPER_BLOCK_MAGIC2 0xdd121031 +#define SUPER_BLOCK_MAGIC3 0x15b6830e +#define POINTER_INVALID 0xffffffffffffffffULL + +#define ATTR_TYPE 0160000 +#define ATTR_REG 0100000 +#define ATTR_DIR 0040000 +#define ATTR_LNK 0120000 + +#define DOUBLE_INDIRECT_SHIFT 2 + +#define LOG_EXTENT_SIZE 3 +struct grub_bfs_extent +{ + grub_uint32_t ag; + grub_uint16_t start; + grub_uint16_t len; +} __attribute__ ((packed)); + +struct grub_bfs_superblock +{ + char label[32]; + grub_uint32_t magic1; + grub_uint32_t unused1; + grub_uint32_t bsize; + grub_uint32_t log2_bsize; + grub_uint8_t unused[20]; + grub_uint32_t magic2; + grub_uint32_t unused2; + grub_uint32_t log2_ag_size; + grub_uint8_t unused3[32]; + grub_uint32_t magic3; + struct grub_bfs_extent root_dir; +} __attribute__ ((packed)); + +struct grub_bfs_inode +{ + grub_uint8_t unused[20]; + grub_uint32_t mode; + grub_uint32_t flags; + grub_uint8_t unused2[8]; + grub_uint64_t mtime; + grub_uint8_t unused3[8]; + struct grub_bfs_extent attr; + grub_uint8_t unused4[12]; + + union + { + struct + { + struct grub_bfs_extent direct[12]; + grub_uint64_t max_direct_range; + struct grub_bfs_extent indirect; + grub_uint64_t max_indirect_range; + struct grub_bfs_extent double_indirect; + grub_uint64_t max_double_indirect_range; + grub_uint64_t size; + grub_uint32_t pad[4]; + } __attribute__ ((packed)); + char inplace_link[144]; + } __attribute__ ((packed)); + grub_uint8_t small_data[0]; +} __attribute__ ((packed)); + +enum +{ + LONG_SYMLINK = 0x40 +}; + +struct grub_bfs_small_data_element_header +{ + grub_uint32_t type; + grub_uint16_t name_len; + grub_uint16_t value_len; +} __attribute__ ((packed)); + +struct grub_bfs_btree_header +{ + grub_uint32_t magic; + grub_uint32_t node_size; + grub_uint32_t level; + grub_uint32_t unused; + grub_uint64_t root; + grub_uint32_t unused2[2]; +} __attribute__ ((packed)); + +struct grub_bfs_btree_node +{ + grub_uint64_t unused; + grub_uint64_t right; + grub_uint64_t overflow; + grub_uint16_t count_keys; + grub_uint16_t total_key_len; +} __attribute__ ((packed)); + +struct grub_bfs_data +{ + struct grub_bfs_superblock sb; + struct grub_bfs_inode ino[0]; +}; + +static grub_err_t +read_extent (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_extent *in, + grub_off_t off, + grub_off_t byteoff, + void *buf, grub_size_t len) +{ + return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) + << grub_bfs_to_cpu32 (sb->log2_ag_size)) + + grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) + , byteoff, + len, buf); +} + +static grub_err_t +read_bfs_file (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + grub_off_t off, void *buf, grub_size_t len, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length)) +{ + if (len == 0) + return GRUB_ERR_NONE; + + if (off + len > grub_bfs_to_cpu64 (ino->size)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); + + if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + { + unsigned i; + grub_uint64_t pos = 0; + for (i = 0; i < ARRAY_SIZE (ino->direct); i++) + { + grub_uint64_t newpos; + newpos = pos + (grub_bfs_to_cpu16 (ino->direct[i].len) + << grub_bfs_to_cpu32 (sb->log2_bsize)); + if (newpos > off) + { + grub_size_t read_size; + grub_err_t err; + read_size = newpos - off; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &ino->direct[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; + if (err) + return err; + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + if (len == 0) + return GRUB_ERR_NONE; + } + pos = newpos; + } + } + + if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + return grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); + + if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + { + unsigned i; + struct grub_bfs_extent *entries; + grub_size_t nentries; + grub_err_t err; + grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); + nentries = (grub_bfs_to_cpu16 (ino->indirect.len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + entries = grub_malloc (nentries << LOG_EXTENT_SIZE); + if (!entries) + return grub_errno; + err = read_extent (disk, sb, &ino->indirect, 0, 0, + entries, nentries << LOG_EXTENT_SIZE); + for (i = 0; i < nentries; i++) + { + grub_uint64_t newpos; + newpos = pos + (grub_bfs_to_cpu16 (entries[i].len) + << grub_bfs_to_cpu32 (sb->log2_bsize)); + if (newpos > off) + { + grub_size_t read_size; + read_size = newpos - off; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &entries[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; + if (err) + { + grub_free (entries); + return err; + } + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + if (len == 0) + { + grub_free (entries); + return GRUB_ERR_NONE; + } + } + pos = newpos; + } + grub_free (entries); + } + + if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + return grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); + + { + struct grub_bfs_extent *l1_entries, *l2_entries; + grub_size_t nl1_entries, nl2_entries; + grub_off_t last_l1n = ~0ULL; + grub_err_t err; + nl1_entries = (grub_bfs_to_cpu16 (ino->double_indirect.len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + l1_entries = grub_malloc (nl1_entries << LOG_EXTENT_SIZE); + if (!l1_entries) + return grub_errno; + nl2_entries = 0; + l2_entries = grub_malloc (1 << (DOUBLE_INDIRECT_SHIFT + + grub_bfs_to_cpu32 (sb->log2_bsize))); + if (!l2_entries) + { + grub_free (l1_entries); + return grub_errno; + } + err = read_extent (disk, sb, &ino->double_indirect, 0, 0, + l1_entries, nl1_entries << LOG_EXTENT_SIZE); + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + + while (len > 0) + { + grub_off_t boff, l2n, l1n; + grub_size_t read_size; + grub_off_t double_indirect_offset; + double_indirect_offset = off + - grub_bfs_to_cpu64 (ino->max_indirect_range); + boff = (double_indirect_offset + & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) - 1)); + l2n = ((double_indirect_offset >> (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) + & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT)) + - 1)); + l1n = (double_indirect_offset >> (2 * grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + 2 * DOUBLE_INDIRECT_SHIFT)); + if (l1n > nl1_entries) + { + grub_free (l1_entries); + grub_free (l2_entries); + return grub_error (GRUB_ERR_BAD_FS, + "incorrect double-indirect block"); + } + if (l1n != last_l1n) + { + nl2_entries = (grub_bfs_to_cpu16 (l1_entries[l1n].len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + if (nl2_entries > (1U << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT))) + nl2_entries = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT)); + err = read_extent (disk, sb, &l1_entries[l1n], 0, 0, + l2_entries, nl2_entries << LOG_EXTENT_SIZE); + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + last_l1n = l1n; + } + if (l2n > nl2_entries) + { + grub_free (l1_entries); + grub_free (l2_entries); + return grub_error (GRUB_ERR_BAD_FS, + "incorrect double-indirect block"); + } + + read_size = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) - boff; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &l2_entries[l2n], 0, boff, + buf, read_size); + disk->read_hook = 0; + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + } + return GRUB_ERR_NONE; + } +} + +static int +iterate_in_b_tree (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + int (*hook) (const char *name, grub_uint64_t value)) +{ + struct grub_bfs_btree_header head; + grub_err_t err; + int level; + grub_uint64_t node_off; + + err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); + if (err) + return 0; + node_off = grub_bfs_to_cpu64 (head.root); + + level = grub_bfs_to_cpu32 (head.level) - 1; + while (level--) + { + struct grub_bfs_btree_node node; + grub_uint64_t key_value; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + &key_value, sizeof (grub_uint64_t), 0); + if (err) + return 0; + + node_off = grub_bfs_to_cpu64 (key_value); + } + + while (1) + { + struct grub_bfs_btree_node node; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return 0; + { + char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + unsigned i; + grub_uint16_t start = 0, end = 0; + + err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); + if (err) + return 0; + key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8), + keylen_idx, grub_bfs_to_cpu16 (node.count_keys) + * 2, 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, grub_bfs_to_cpu16 (node.count_keys) + * 8, 0); + if (err) + return 0; + + for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + { + char c; + start = end; + end = grub_bfs_to_cpu16 (keylen_idx[i]); + c = key_data[end]; + key_data[end] = 0; + if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) + return 1; + key_data[end] = c; + } + node_off = grub_bfs_to_cpu64 (node.right); + if (node_off == POINTER_INVALID) + return 0; + } + } +} + +static grub_err_t +find_in_b_tree (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, const char *name, + grub_uint64_t *res) +{ + struct grub_bfs_btree_header head; + grub_err_t err; + int level; + grub_uint64_t node_off; + + err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); + if (err) + return err; + node_off = grub_bfs_to_cpu64 (head.root); + + level = grub_bfs_to_cpu32 (head.level) - 1; + while (1) + { + struct grub_bfs_btree_node node; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return err; + if (node.count_keys == 0) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", + name); + { + char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + unsigned i; + grub_uint16_t start = 0, end = 0; + err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); + if (err) + return err; + key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) +grub_bfs_to_cpu16 (node.total_key_len), + 8), + keylen_idx, grub_bfs_to_cpu16 (node.count_keys) + * 2, 0); + if (err) + return err; + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, grub_bfs_to_cpu16 (node.count_keys) + * 8, 0); + if (err) + return err; + + for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + { + int cmp; + char c; + start = end; + end = grub_bfs_to_cpu16 (keylen_idx[i]); + if (grub_bfs_to_cpu16 (node.total_key_len) <= end) + end = grub_bfs_to_cpu16 (node.total_key_len); + c = key_data[end]; + key_data[end] = 0; + cmp = grub_strcmp (key_data + start, name); + key_data[end] = c; + if (cmp == 0 && level == 0) + { + *res = grub_bfs_to_cpu64 (key_values[i]); + return GRUB_ERR_NONE; + } + if (cmp >= 0 && level != 0) + { + node_off = grub_bfs_to_cpu64 (key_values[i]); + break; + } + } + if (i < grub_bfs_to_cpu16 (node.count_keys)) + { + level--; + continue; + } + if (node.overflow != POINTER_INVALID) + { + node_off = grub_bfs_to_cpu64 (node.overflow); + /* This level-- isn't specified but is needed. */ + level--; + continue; + } + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", + name); + } + } +} + +static grub_err_t +hop_level (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + struct grub_bfs_inode *ino, + const char *name) +{ + grub_err_t err; + grub_uint64_t res; + + if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) != ATTR_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + err = find_in_b_tree (disk, sb, ino, name, &res); + if (err) + return err; + + return grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) ino); +} + +static grub_err_t +find_file (const char *path, grub_disk_t disk, + const struct grub_bfs_superblock *sb, + struct grub_bfs_inode *ino) +{ + char *ptr, *ptr2; + char *alloc = NULL; + grub_err_t err; + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } old_ino; + unsigned symlinks_max = 32; + + err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return err; + + ptr = (char *) path; + while (1) + { + while (*ptr == '/') + ptr++; + if (*ptr == 0) + { + grub_free (alloc); + return GRUB_ERR_NONE; + } + ptr2 = grub_strchr (ptr, '/'); + grub_memcpy (&old_ino, ino, grub_bfs_to_cpu32 (sb->bsize)); + if (ptr2) + { + char component[ptr2 - ptr + 1]; + grub_memcpy (component, ptr, ptr2 - ptr); + component[ptr2 - ptr] = 0; + err = hop_level (disk, sb, ino, component); + } + else + err = hop_level (disk, sb, ino, ptr); + if (err) + return err; + + if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) == ATTR_LNK)) + { + char *old_alloc = alloc; + if (--symlinks_max == 0) + { + grub_free (alloc); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + } + + if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK) + { + grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + + + symsize + 1); + if (!alloc) + { + grub_free (alloc); + return grub_errno; + } + grub_free (old_alloc); + err = read_bfs_file (disk, sb, ino, + 0, alloc, symsize, 0); + if (err) + { + grub_free (alloc); + return err; + } + alloc[symsize] = 0; + } + else + { + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + + sizeof (ino->inplace_link) + 1); + if (!alloc) + { + grub_free (alloc); + return grub_errno; + } + grub_free (old_alloc); + grub_memcpy (alloc, ino->inplace_link, + sizeof (ino->inplace_link)); + alloc[sizeof (ino->inplace_link)] = 0; + } + if (alloc[0] == '/') + { + err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + { + grub_free (alloc); + return err; + } + } + else + grub_memcpy (ino, &old_ino, grub_bfs_to_cpu32 (sb->bsize)); + ptr = alloc + grub_strlen (alloc); + if (ptr2) + ptr = grub_stpcpy (ptr, ptr2); + *ptr = 0; + ptr = ptr2 = alloc; + continue; + } + + if (!ptr2) + { + grub_free (alloc); + return GRUB_ERR_NONE; + } + ptr = ptr2 + 1; + } +} + +static grub_err_t +mount (grub_disk_t disk, struct grub_bfs_superblock *sb) +{ + grub_err_t err; + err = grub_disk_read (disk, 1, 0, + sizeof (*sb), sb); + if (err == GRUB_ERR_OUT_OF_RANGE) + return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + if (err) + return err; + if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 + || grub_bfs_to_cpu32 (sb->magic2) != SUPER_BLOCK_MAGIC2 + || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 + || (grub_bfs_to_cpu32 (sb->bsize) + != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) + return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bfs_dir (grub_device_t device, const char *path, + int (*hook_in) (const char *filename, + const struct grub_dirhook_info *info)) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + auto int hook (const char *name, grub_uint64_t value); + + int hook (const char *name, grub_uint64_t value) + { + grub_err_t err2; + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + struct grub_dirhook_info info; + + err2 = grub_disk_read (device->disk, value + << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9) + , 0, + grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); + if (err2) + { + grub_print_error (); + return 0; + } + + info.mtimeset = 1; + info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; + info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); + return hook_in (name, &info); + } + err = mount (device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + err = find_file (path, device->disk, &sb, &ino.ino); + if (err) + return err; + if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + iterate_in_b_tree (device->disk, &sb, &ino.ino, hook); + } + + return grub_errno; +} + +static grub_err_t +grub_bfs_open (struct grub_file *file, const char *name) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + err = mount (file->device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + struct grub_bfs_data *data; + err = find_file (name, file->device->disk, &sb, &ino.ino); + if (err) + return err; + if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_REG)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + data = grub_zalloc (sizeof (struct grub_bfs_data) + + grub_bfs_to_cpu32 (sb.bsize)); + if (!data) + return grub_errno; + data->sb = sb; + grub_memcpy (&data->ino, &ino, grub_bfs_to_cpu32 (sb.bsize)); + file->data = data; + file->size = grub_bfs_to_cpu64 (ino.ino.size); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bfs_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_err_t err; + struct grub_bfs_data *data = file->data; + + err = read_bfs_file (file->device->disk, &data->sb, + data->ino, + file->offset, buf, len, file->read_hook); + if (err) + return -1; + return len; +} + +static grub_err_t +grub_bfs_label (grub_device_t device, char **label) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + *label = 0; + + err = mount (device->disk, &sb); + if (err) + return err; + + *label = grub_strndup (sb.label, sizeof (sb.label)); + return GRUB_ERR_NONE; +} + +static grub_ssize_t +read_bfs_attr (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + const char *name, + void *buf, grub_size_t len) +{ + grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data; + grub_uint8_t *end = ((grub_uint8_t *) ino + + grub_bfs_to_cpu32 (sb->bsize)); + + while (ptr + sizeof (struct grub_bfs_small_data_element_header) < end) + { + struct grub_bfs_small_data_element_header *el; + char *el_name; + grub_uint8_t *data; + el = (struct grub_bfs_small_data_element_header *) ptr; + if (el->name_len == 0) + break; + el_name = (char *) (el + 1); + data = (grub_uint8_t *) el_name + grub_bfs_to_cpu16 (el->name_len) + 3; + ptr = data + grub_bfs_to_cpu16 (el->value_len) + 1; + if (grub_memcmp (name, el_name, grub_bfs_to_cpu16 (el->name_len)) == 0 + && name[el->name_len] == 0) + { + grub_size_t copy; + copy = len; + if (grub_bfs_to_cpu16 (el->value_len) > copy) + copy = grub_bfs_to_cpu16 (el->value_len); + grub_memcpy (buf, data, copy); + return copy; + } + } + + if (ino->attr.len != 0) + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } ino2; + grub_size_t read; + grub_err_t err; + grub_uint64_t res; + + err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return -1; + + err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); + if (err) + return -1; + grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) + , 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); + read = grub_bfs_to_cpu64 (ino2.ino.size); + if (read > len) + read = len; + + err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); + if (err) + return -1; + return read; + } + return -1; +} + +static grub_err_t +grub_bfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + *uuid = 0; + + err = mount (device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + grub_uint64_t vid; + + err = read_extent (device->disk, &sb, &sb.root_dir, 0, 0, + &ino, grub_bfs_to_cpu32 (sb.bsize)); + if (err) + return err; + if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", + &vid, 8) == 8) + *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); + } + return GRUB_ERR_NONE; +} + + +static struct grub_fs grub_bfs_fs = { + .name = "bfs", + .dir = grub_bfs_dir, + .open = grub_bfs_open, + .read = grub_bfs_read, + .close = grub_bfs_close, + .label = grub_bfs_label, + .uuid = grub_bfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif +}; + +GRUB_MOD_INIT (bfs) +{ + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); + grub_fs_register (&grub_bfs_fs); +} + +GRUB_MOD_FINI (bfs) +{ + grub_fs_unregister (&grub_bfs_fs); +} From c4a1628f6765a330f7d1afc40cefc139512b9e6c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:27:53 +0100 Subject: [PATCH 125/315] * grub-core/fs/bfs.c: Run indent. --- ChangeLog | 4 + grub-core/fs/bfs.c | 220 +++++++++++++++++++++++---------------------- 2 files changed, 115 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8ea7974c..c52bff5b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: Run indent. + 2011-10-30 Vladimir Serbinenko BFS implementation based on the specification. diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 6f6ebf908..7b6e359ae 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -141,15 +141,12 @@ static grub_err_t read_extent (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_extent *in, - grub_off_t off, - grub_off_t byteoff, - void *buf, grub_size_t len) + grub_off_t off, grub_off_t byteoff, void *buf, grub_size_t len) { return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) << grub_bfs_to_cpu32 (sb->log2_ag_size)) + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) - , byteoff, + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), byteoff, len, buf); } @@ -159,13 +156,15 @@ read_bfs_file (grub_disk_t disk, const struct grub_bfs_inode *ino, grub_off_t off, void *buf, grub_size_t len, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length)) + unsigned offset, + unsigned length)) { if (len == 0) return GRUB_ERR_NONE; if (off + len > grub_bfs_to_cpu64 (ino->size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "attempt to read past the end of file"); if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) { @@ -210,11 +209,10 @@ read_bfs_file (grub_disk_t disk, grub_err_t err; grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); nentries = (grub_bfs_to_cpu16 (ino->indirect.len) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE)); + << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); entries = grub_malloc (nentries << LOG_EXTENT_SIZE); if (!entries) - return grub_errno; + return grub_errno; err = read_extent (disk, sb, &ino->indirect, 0, 0, entries, nentries << LOG_EXTENT_SIZE); for (i = 0; i < nentries; i++) @@ -260,8 +258,7 @@ read_bfs_file (grub_disk_t disk, grub_off_t last_l1n = ~0ULL; grub_err_t err; nl1_entries = (grub_bfs_to_cpu16 (ino->double_indirect.len) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE)); + << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); l1_entries = grub_malloc (nl1_entries << LOG_EXTENT_SIZE); if (!l1_entries) return grub_errno; @@ -271,7 +268,7 @@ read_bfs_file (grub_disk_t disk, if (!l2_entries) { grub_free (l1_entries); - return grub_errno; + return grub_errno; } err = read_extent (disk, sb, &ino->double_indirect, 0, 0, l1_entries, nl1_entries << LOG_EXTENT_SIZE); @@ -289,17 +286,17 @@ read_bfs_file (grub_disk_t disk, grub_off_t double_indirect_offset; double_indirect_offset = off - grub_bfs_to_cpu64 (ino->max_indirect_range); - boff = (double_indirect_offset + boff = (double_indirect_offset & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + DOUBLE_INDIRECT_SHIFT)) - 1)); l2n = ((double_indirect_offset >> (grub_bfs_to_cpu32 (sb->log2_bsize) + DOUBLE_INDIRECT_SHIFT)) & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE - + DOUBLE_INDIRECT_SHIFT)) - - 1)); - l1n = (double_indirect_offset >> (2 * grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE - + 2 * DOUBLE_INDIRECT_SHIFT)); + + DOUBLE_INDIRECT_SHIFT)) - 1)); + l1n = + (double_indirect_offset >> + (2 * grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE + + 2 * DOUBLE_INDIRECT_SHIFT)); if (l1n > nl1_entries) { grub_free (l1_entries); @@ -383,9 +380,10 @@ iterate_in_b_tree (grub_disk_t disk, if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; @@ -395,7 +393,7 @@ iterate_in_b_tree (grub_disk_t disk, while (1) { - struct grub_bfs_btree_node node; + struct grub_bfs_btree_node node; err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); if (err) return 0; @@ -406,24 +404,28 @@ iterate_in_b_tree (grub_disk_t disk, unsigned i; grub_uint16_t start = 0, end = 0; - err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); if (err) return 0; key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; - err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8), - keylen_idx, grub_bfs_to_cpu16 (node.count_keys) - * 2, 0); + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8), keylen_idx, + grub_bfs_to_cpu16 (node.count_keys) * 2, 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, - key_values, grub_bfs_to_cpu16 (node.count_keys) - * 8, 0); + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, + grub_bfs_to_cpu16 (node.count_keys) * 8, 0); if (err) return 0; @@ -449,7 +451,7 @@ static grub_err_t find_in_b_tree (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_inode *ino, const char *name, - grub_uint64_t *res) + grub_uint64_t * res) { struct grub_bfs_btree_header head; grub_err_t err; @@ -464,7 +466,7 @@ find_in_b_tree (grub_disk_t disk, level = grub_bfs_to_cpu32 (head.level) - 1; while (1) { - struct grub_bfs_btree_node node; + struct grub_bfs_btree_node node; err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); if (err) return err; @@ -477,26 +479,28 @@ find_in_b_tree (grub_disk_t disk, grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; - err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); if (err) return err; key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; - err = read_bfs_file (disk, sb, ino, node_off - + - ALIGN_UP (sizeof (node) +grub_bfs_to_cpu16 (node.total_key_len), - 8), - keylen_idx, grub_bfs_to_cpu16 (node.count_keys) - * 2, 0); + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node.total_key_len), + 8), keylen_idx, + grub_bfs_to_cpu16 (node.count_keys) * 2, 0); if (err) return err; - err = read_bfs_file (disk, sb, ino, node_off - - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, - key_values, grub_bfs_to_cpu16 (node.count_keys) - * 8, 0); + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, + grub_bfs_to_cpu16 (node.count_keys) * 8, 0); if (err) return err; @@ -544,8 +548,7 @@ find_in_b_tree (grub_disk_t disk, static grub_err_t hop_level (grub_disk_t disk, const struct grub_bfs_superblock *sb, - struct grub_bfs_inode *ino, - const char *name) + struct grub_bfs_inode *ino, const char *name) { grub_err_t err; grub_uint64_t res; @@ -564,13 +567,13 @@ hop_level (grub_disk_t disk, static grub_err_t find_file (const char *path, grub_disk_t disk, - const struct grub_bfs_superblock *sb, - struct grub_bfs_inode *ino) + const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino) { char *ptr, *ptr2; char *alloc = NULL; grub_err_t err; - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; } old_ino; @@ -619,7 +622,6 @@ find_file (const char *path, grub_disk_t disk, { grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) - + symsize + 1); if (!alloc) { @@ -627,8 +629,7 @@ find_file (const char *path, grub_disk_t disk, return grub_errno; } grub_free (old_alloc); - err = read_bfs_file (disk, sb, ino, - 0, alloc, symsize, 0); + err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0); if (err) { grub_free (alloc); @@ -638,7 +639,7 @@ find_file (const char *path, grub_disk_t disk, } else { - alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + sizeof (ino->inplace_link) + 1); if (!alloc) { @@ -653,7 +654,7 @@ find_file (const char *path, grub_disk_t disk, if (alloc[0] == '/') { err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, - grub_bfs_to_cpu32 (sb->bsize)); + grub_bfs_to_cpu32 (sb->bsize)); if (err) { grub_free (alloc); @@ -683,8 +684,7 @@ static grub_err_t mount (grub_disk_t disk, struct grub_bfs_superblock *sb) { grub_err_t err; - err = grub_disk_read (disk, 1, 0, - sizeof (*sb), sb); + err = grub_disk_read (disk, 1, 0, sizeof (*sb), sb); if (err == GRUB_ERR_OUT_OF_RANGE) return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); if (err) @@ -692,7 +692,7 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 || grub_bfs_to_cpu32 (sb->magic2) != SUPER_BLOCK_MAGIC2 || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 - || (grub_bfs_to_cpu32 (sb->bsize) + || (grub_bfs_to_cpu32 (sb->bsize) != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); return GRUB_ERR_NONE; @@ -701,7 +701,7 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) static grub_err_t grub_bfs_dir (grub_device_t device, const char *path, int (*hook_in) (const char *filename, - const struct grub_dirhook_info *info)) + const struct grub_dirhook_info * info)) { struct grub_bfs_superblock sb; grub_err_t err; @@ -710,21 +710,21 @@ grub_bfs_dir (grub_device_t device, const char *path, int hook (const char *name, grub_uint64_t value) { grub_err_t err2; - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; struct grub_dirhook_info info; err2 = grub_disk_read (device->disk, value - << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9) - , 0, + << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9), 0, grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); if (err2) { grub_print_error (); return 0; - } + } info.mtimeset = 1; info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; @@ -736,7 +736,8 @@ grub_bfs_dir (grub_device_t device, const char *path, return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -762,7 +763,8 @@ grub_bfs_open (struct grub_file *file, const char *name) return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -799,10 +801,9 @@ grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) { grub_err_t err; struct grub_bfs_data *data = file->data; - + err = read_bfs_file (file->device->disk, &data->sb, - data->ino, - file->offset, buf, len, file->read_hook); + data->ino, file->offset, buf, len, file->read_hook); if (err) return -1; return len; @@ -828,12 +829,10 @@ static grub_ssize_t read_bfs_attr (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_inode *ino, - const char *name, - void *buf, grub_size_t len) + const char *name, void *buf, grub_size_t len) { grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data; - grub_uint8_t *end = ((grub_uint8_t *) ino - + grub_bfs_to_cpu32 (sb->bsize)); + grub_uint8_t *end = ((grub_uint8_t *) ino + grub_bfs_to_cpu32 (sb->bsize)); while (ptr + sizeof (struct grub_bfs_small_data_element_header) < end) { @@ -859,36 +858,36 @@ read_bfs_attr (grub_disk_t disk, } if (ino->attr.len != 0) - { - union { - struct grub_bfs_inode ino; - grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; - } ino2; - grub_size_t read; - grub_err_t err; - grub_uint64_t res; + { + union + { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } ino2; + grub_size_t read; + grub_err_t err; + grub_uint64_t res; - err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, - grub_bfs_to_cpu32 (sb->bsize)); - if (err) - return -1; + err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return -1; - err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); - if (err) - return -1; - grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) - , 0, - grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); - read = grub_bfs_to_cpu64 (ino2.ino.size); - if (read > len) - read = len; + err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); + if (err) + return -1; + grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); + read = grub_bfs_to_cpu64 (ino2.ino.size); + if (read > len) + read = len; - err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); - if (err) - return -1; - return read; - } + err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); + if (err) + return -1; + return read; + } return -1; } @@ -905,7 +904,8 @@ grub_bfs_uuid (grub_device_t device, char **uuid) return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -917,7 +917,8 @@ grub_bfs_uuid (grub_device_t device, char **uuid) return err; if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", &vid, 8) == 8) - *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); + *uuid = + grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); } return GRUB_ERR_NONE; } @@ -938,7 +939,8 @@ static struct grub_fs grub_bfs_fs = { GRUB_MOD_INIT (bfs) { - COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == + sizeof (struct grub_bfs_extent)); grub_fs_register (&grub_bfs_fs); } From 785ab8c76053d18a1b80046d599e0ed7f8680f00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 14:17:44 +0100 Subject: [PATCH 126/315] * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. --- ChangeLog | 4 ++++ grub-core/fs/bfs.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c52bff5b9..8ff87aebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. + 2011-10-30 Vladimir Serbinenko * grub-core/fs/bfs.c: Run indent. diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 7b6e359ae..c16a50f39 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -146,7 +146,8 @@ read_extent (grub_disk_t disk, return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) << grub_bfs_to_cpu32 (sb->log2_ag_size)) + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), byteoff, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), byteoff, len, buf); } @@ -383,7 +384,8 @@ iterate_in_b_tree (grub_disk_t disk, + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; @@ -415,7 +417,8 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) * 2, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off @@ -423,9 +426,11 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), key_values, - grub_bfs_to_cpu16 (node.count_keys) * 8, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), 0); if (err) return 0; @@ -434,6 +439,8 @@ iterate_in_b_tree (grub_disk_t disk, char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); + if (grub_bfs_to_cpu16 (node.total_key_len) <= end) + end = grub_bfs_to_cpu16 (node.total_key_len); c = key_data[end]; key_data[end] = 0; if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) @@ -490,7 +497,8 @@ find_in_b_tree (grub_disk_t disk, ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) * 2, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), 0); if (err) return err; err = read_bfs_file (disk, sb, ino, node_off @@ -498,9 +506,11 @@ find_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), key_values, - grub_bfs_to_cpu16 (node.count_keys) * 8, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), 0); if (err) return err; @@ -561,7 +571,8 @@ hop_level (grub_disk_t disk, return err; return grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb->bsize), (char *) ino); } @@ -718,7 +729,8 @@ grub_bfs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; err2 = grub_disk_read (device->disk, value - << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb.log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); if (err2) { @@ -877,7 +889,8 @@ read_bfs_attr (grub_disk_t disk, if (err) return -1; grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); read = grub_bfs_to_cpu64 (ino2.ino.size); if (read > len) @@ -916,7 +929,7 @@ grub_bfs_uuid (grub_device_t device, char **uuid) if (err) return err; if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", - &vid, 8) == 8) + &vid, sizeof (vid)) == sizeof (vid)) *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); } From 80f9f81424d72bea0588b48c428bb8d39a276f33 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 14:25:53 +0100 Subject: [PATCH 127/315] Fix a mistake in previous commit --- grub-core/fs/bfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index c16a50f39..a92f3522c 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -385,7 +385,7 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node.total_key_len), 8) + grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), + * sizeof (grub_uint16_t), &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; From eb0b6b45f380ca4831358aa14aa25391f2d9800f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 16:10:18 +0100 Subject: [PATCH 128/315] Leverage BFS implementation to read AFS. * Makefile.util.def (libgrubmods): Add afs.c. * grub-core/Makefile.core.def (afs): New module * grub-core/fs/afs.c: New file. * grub-core/fs/bfs.c [MODE_AFS]: Adapt for AFS. --- ChangeLog | 11 +- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/afs.c | 3 + grub-core/fs/bfs.c | 211 +++++++++++++++++++++++++----------- 5 files changed, 168 insertions(+), 63 deletions(-) create mode 100644 grub-core/fs/afs.c diff --git a/ChangeLog b/ChangeLog index 8ff87aebd..8f44f2080 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,15 @@ 2011-10-30 Vladimir Serbinenko - * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. + Leverage BFS implementation to read AFS. + + * Makefile.util.def (libgrubmods): Add afs.c. + * grub-core/Makefile.core.def (afs): New module + * grub-core/fs/afs.c: New file. + * grub-core/fs/bfs.c [MODE_AFS]: Adapt for AFS. + +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: Macroify and add some necessary sanity checks. 2011-10-30 Vladimir Serbinenko diff --git a/Makefile.util.def b/Makefile.util.def index 053ff4340..a839920d5 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,6 +55,7 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; + common = grub-core/fs/afs.c; common = grub-core/fs/bfs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c6127b28f..2b72d8429 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,6 +970,11 @@ module = { common = fs/affs.c; }; +module = { + name = afs; + common = fs/afs.c; +}; + module = { name = bfs; common = fs/bfs.c; diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c new file mode 100644 index 000000000..00a5e3113 --- /dev/null +++ b/grub-core/fs/afs.c @@ -0,0 +1,3 @@ +#define MODE_AFS 1 +#include "bfs.c" + diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index a92f3522c..fe8f991c4 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -31,11 +31,29 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#ifdef MODE_AFS +#define BTREE_ALIGN 4 +#define SUPERBLOCK 2 +#else +#define BTREE_ALIGN 8 +#define SUPERBLOCK 1 +#endif + #define grub_bfs_to_cpu16 grub_le_to_cpu16 #define grub_bfs_to_cpu32 grub_le_to_cpu32 #define grub_bfs_to_cpu64 grub_le_to_cpu64 +#ifdef MODE_AFS +#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu32 +#else +#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu16 +#endif + +#ifdef MODE_AFS +#define SUPER_BLOCK_MAGIC1 0x41465331 +#else #define SUPER_BLOCK_MAGIC1 0x42465331 +#endif #define SUPER_BLOCK_MAGIC2 0xdd121031 #define SUPER_BLOCK_MAGIC3 0x15b6830e #define POINTER_INVALID 0xffffffffffffffffULL @@ -76,7 +94,11 @@ struct grub_bfs_inode grub_uint8_t unused[20]; grub_uint32_t mode; grub_uint32_t flags; +#ifdef MODE_AFS + grub_uint8_t unused2[12]; +#else grub_uint8_t unused2[8]; +#endif grub_uint64_t mtime; grub_uint8_t unused3[8]; struct grub_bfs_extent attr; @@ -115,10 +137,17 @@ struct grub_bfs_small_data_element_header struct grub_bfs_btree_header { grub_uint32_t magic; +#ifdef MODE_AFS + grub_uint64_t root; + grub_uint32_t level; + grub_uint32_t node_size; + grub_uint32_t unused; +#else grub_uint32_t node_size; grub_uint32_t level; grub_uint32_t unused; grub_uint64_t root; +#endif grub_uint32_t unused2[2]; } __attribute__ ((packed)); @@ -127,8 +156,13 @@ struct grub_bfs_btree_node grub_uint64_t unused; grub_uint64_t right; grub_uint64_t overflow; +#ifdef MODE_AFS + grub_uint32_t count_keys; + grub_uint32_t total_key_len; +#else grub_uint16_t count_keys; grub_uint16_t total_key_len; +#endif } __attribute__ ((packed)); struct grub_bfs_data @@ -143,14 +177,30 @@ read_extent (grub_disk_t disk, const struct grub_bfs_extent *in, grub_off_t off, grub_off_t byteoff, void *buf, grub_size_t len) { +#ifdef MODE_AFS return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) - << grub_bfs_to_cpu32 (sb->log2_ag_size)) - + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS), byteoff, - len, buf); + << (grub_bfs_to_cpu32 (sb->log2_ag_size) + - GRUB_DISK_SECTOR_BITS)) + + ((grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS))), + byteoff, len, buf); +#else + return grub_disk_read (disk, (((grub_bfs_to_cpu32 (in->ag) + << grub_bfs_to_cpu32 (sb->log2_ag_size)) + + grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS)), + byteoff, len, buf); +#endif } +#ifdef MODE_AFS +#define RANGE_SHIFT grub_bfs_to_cpu32 (sb->log2_bsize) +#else +#define RANGE_SHIFT 0 +#endif + static grub_err_t read_bfs_file (grub_disk_t disk, const struct grub_bfs_superblock *sb, @@ -167,7 +217,7 @@ read_bfs_file (grub_disk_t disk, return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); - if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) { unsigned i; grub_uint64_t pos = 0; @@ -199,16 +249,17 @@ read_bfs_file (grub_disk_t disk, } } - if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) return grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); - if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) { unsigned i; struct grub_bfs_extent *entries; grub_size_t nentries; grub_err_t err; - grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); + grub_uint64_t pos = (grub_bfs_to_cpu64 (ino->max_direct_range) + << RANGE_SHIFT); nentries = (grub_bfs_to_cpu16 (ino->indirect.len) << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); entries = grub_malloc (nentries << LOG_EXTENT_SIZE); @@ -250,7 +301,7 @@ read_bfs_file (grub_disk_t disk, grub_free (entries); } - if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) return grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); { @@ -382,11 +433,12 @@ iterate_in_b_tree (grub_disk_t disk, return 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node.total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - &key_value, sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead (node. + total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), &key_value, + sizeof (grub_uint64_t), 0); if (err) return 0; @@ -400,47 +452,46 @@ iterate_in_b_tree (grub_disk_t disk, if (err) return 0; { - char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; - grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; - grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + grub_bfs_to_cpu_treehead (node.total_key_len), 0); if (err) return 0; - key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), BTREE_ALIGN), + keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - key_values, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint64_t), 0); if (err) return 0; - for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + for (i = 0; i < grub_bfs_to_cpu_treehead (node.count_keys); i++) { char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); - if (grub_bfs_to_cpu16 (node.total_key_len) <= end) - end = grub_bfs_to_cpu16 (node.total_key_len); + if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end) + end = grub_bfs_to_cpu_treehead (node.total_key_len); c = key_data[end]; key_data[end] = 0; if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) @@ -481,47 +532,47 @@ find_in_b_tree (grub_disk_t disk, return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", name); { - char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; - grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; - grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + grub_bfs_to_cpu_treehead (node.total_key_len), 0); if (err) return err; - key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node.total_key_len), - 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), 0); + grub_bfs_to_cpu_treehead (node. + total_key_len), + BTREE_ALIGN), keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), 0); if (err) return err; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - key_values, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint64_t), 0); if (err) return err; - for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + for (i = 0; i < grub_bfs_to_cpu_treehead (node.count_keys); i++) { int cmp; char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); - if (grub_bfs_to_cpu16 (node.total_key_len) <= end) - end = grub_bfs_to_cpu16 (node.total_key_len); + if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end) + end = grub_bfs_to_cpu_treehead (node.total_key_len); c = key_data[end]; key_data[end] = 0; cmp = grub_strcmp (key_data + start, name); @@ -537,7 +588,7 @@ find_in_b_tree (grub_disk_t disk, break; } } - if (i < grub_bfs_to_cpu16 (node.count_keys)) + if (i < grub_bfs_to_cpu_treehead (node.count_keys)) { level--; continue; @@ -629,7 +680,9 @@ find_file (const char *path, grub_disk_t disk, "too deep nesting of symlinks"); } +#ifndef MODE_AFS if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK) +#endif { grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) @@ -648,6 +701,7 @@ find_file (const char *path, grub_disk_t disk, } alloc[symsize] = 0; } +#ifndef MODE_AFS else { alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) @@ -662,6 +716,7 @@ find_file (const char *path, grub_disk_t disk, sizeof (ino->inplace_link)); alloc[sizeof (ino->inplace_link)] = 0; } +#endif if (alloc[0] == '/') { err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, @@ -695,9 +750,15 @@ static grub_err_t mount (grub_disk_t disk, struct grub_bfs_superblock *sb) { grub_err_t err; - err = grub_disk_read (disk, 1, 0, sizeof (*sb), sb); + err = grub_disk_read (disk, SUPERBLOCK, 0, sizeof (*sb), sb); if (err == GRUB_ERR_OUT_OF_RANGE) - return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return grub_error (GRUB_ERR_BAD_FS, +#ifdef MODE_AFS + "not an AFS filesystem" +#else + "not a BFS filesystem" +#endif + ); if (err) return err; if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 @@ -705,7 +766,13 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 || (grub_bfs_to_cpu32 (sb->bsize) != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) - return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return grub_error (GRUB_ERR_BAD_FS, +#ifdef MODE_AFS + "not an AFS filesystem" +#else + "not a BFS filesystem" +#endif + ); return GRUB_ERR_NONE; } @@ -739,7 +806,12 @@ grub_bfs_dir (grub_device_t device, const char *path, } info.mtimeset = 1; +#ifdef MODE_AFS + info.mtime = + grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0); +#else info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; +#endif info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); return hook_in (name, &info); } @@ -785,7 +857,7 @@ grub_bfs_open (struct grub_file *file, const char *name) if (err) return err; if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_REG)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); data = grub_zalloc (sizeof (struct grub_bfs_data) + grub_bfs_to_cpu32 (sb.bsize)); @@ -837,6 +909,7 @@ grub_bfs_label (grub_device_t device, char **label) return GRUB_ERR_NONE; } +#ifndef MODE_AFS static grub_ssize_t read_bfs_attr (grub_disk_t disk, const struct grub_bfs_superblock *sb, @@ -935,29 +1008,43 @@ grub_bfs_uuid (grub_device_t device, char **uuid) } return GRUB_ERR_NONE; } - +#endif static struct grub_fs grub_bfs_fs = { +#ifdef MODE_AFS + .name = "afs", +#else .name = "bfs", +#endif .dir = grub_bfs_dir, .open = grub_bfs_open, .read = grub_bfs_read, .close = grub_bfs_close, .label = grub_bfs_label, +#ifndef MODE_AFS .uuid = grub_bfs_uuid, +#endif #ifdef GRUB_UTIL .reserved_first_sector = 1, #endif }; +#ifdef MODE_AFS +GRUB_MOD_INIT (afs) +#else GRUB_MOD_INIT (bfs) +#endif { COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); grub_fs_register (&grub_bfs_fs); } +#ifdef MODE_AFS +GRUB_MOD_FINI (afs) +#else GRUB_MOD_FINI (bfs) +#endif { grub_fs_unregister (&grub_bfs_fs); } From 94ef05c2652e78d2b6be32829530efa5eb9d7ac0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 19:30:04 +0100 Subject: [PATCH 129/315] * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type string. --- ChangeLog | 5 +++++ grub-core/loader/mips/linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8f44f2080..3e9f8a640 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type + string. + 2011-10-30 Vladimir Serbinenko Leverage BFS implementation to read AFS. diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 2b4875983..17c2656e2 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); const char loongson_machtypes[][60] = { [GRUB_ARCH_MACHINE_YEELOONG] = "machtype=lemote-yeeloong-2f-8.9inches", - [GRUB_ARCH_MACHINE_FULOONG2F] = "machtype=lemote-fuloong-2f-unknown", + [GRUB_ARCH_MACHINE_FULOONG2F] = "machtype=lemote-fuloong-2f-box", [GRUB_ARCH_MACHINE_FULOONG2E] = "machtype=lemote-fuloong-2e-unknown" }; #endif From 45cdd3ea372ff15b68b622e2791b61edc6d0ac21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 20:14:57 +0100 Subject: [PATCH 130/315] Fix JFS file name length limitations. * grub-core/fs/jfs.c (grub_jfs_inode): Fix in-place symlink length. (grub_jfs_diropen): Fix maximum filename length. (grub_jfs_getent): Fix filename length. (grub_jfs_lookup_symlink): Fix size checks. --- ChangeLog | 9 +++++++++ grub-core/fs/jfs.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e9f8a640..cfdbfaeda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-30 Vladimir Serbinenko + + Fix JFS file name length limitations. + + * grub-core/fs/jfs.c (grub_jfs_inode): Fix in-place symlink length. + (grub_jfs_diropen): Fix maximum filename length. + (grub_jfs_getent): Fix filename length. + (grub_jfs_lookup_symlink): Fix size checks. + 2011-10-30 Vladimir Serbinenko * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index c5e82bfec..cf7520bb3 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -205,7 +205,7 @@ struct grub_jfs_inode struct { grub_uint8_t unused[32]; - grub_uint8_t path[128]; + grub_uint8_t path[256]; } symlink; } __attribute__ ((packed)); } __attribute__ ((packed)); @@ -238,7 +238,10 @@ struct grub_jfs_diropen struct grub_jfs_leaf_next_dirent *next_leaf; /* The filename and inode of the last read dirent. */ - char name[255]; + /* On-disk name is at most 255 UTF-16 codepoints. + Every UTF-16 codepoint is at most 4 UTF-8 bytes. + */ + char name[256 * 4 + 1]; grub_uint32_t ino; } __attribute__ ((packed)); @@ -479,7 +482,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) struct grub_jfs_leaf_next_dirent *next_leaf; int len; int nextent; - grub_uint16_t filename[255]; + grub_uint16_t filename[256]; auto void addstr (grub_uint16_t *uname, int ulen); @@ -708,14 +711,14 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path, static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) { - grub_uint64_t size = grub_le_to_cpu64 (data->currinode.size); + grub_size_t size = grub_le_to_cpu64 (data->currinode.size); char symlink[size + 1]; if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT) return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - if (size <= 128) - grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128); + if (size <= sizeof (data->currinode.symlink.path)) + grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size); else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0) return grub_errno; From c83a08d84ac9e35cfde2e9df2b660010073e9227 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 20:23:05 +0100 Subject: [PATCH 131/315] Fix iso9660 filename limitations and fix memory leaks. * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end. (grub_iso9660_iterate_dir): Fix slash handling in symlinks. --- ChangeLog | 7 +++++++ grub-core/fs/iso9660.c | 46 ++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfdbfaeda..223afb1e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-30 Vladimir Serbinenko + + Fix iso9660 filename limitations and fix memory leaks. + + * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end. + (grub_iso9660_iterate_dir): Fix slash handling in symlinks. + 2011-10-30 Vladimir Serbinenko Fix JFS file name length limitations. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index a2e731351..d4c52bed4 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -395,7 +395,10 @@ set_rockridge (struct grub_iso9660_data *data) (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, sua_size, sua)) - return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + { + grub_free (sua); + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + } entry = (struct grub_iso9660_susp_entry *) sua; @@ -419,8 +422,12 @@ set_rockridge (struct grub_iso9660_data *data) extensions. */ if (grub_iso9660_susp_iterate (&rootnode, sua_pos, sua_size, susp_iterate)) - return grub_errno; + { + grub_free (sua); + return grub_errno; + } } + grub_free (sua); return GRUB_ERR_NONE; } @@ -516,12 +523,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, { struct grub_iso9660_dir dirent; grub_off_t offset = 0; - char *filename; + char *filename = 0; int filename_alloc = 0; enum grub_fshelp_filetype type; grub_off_t len; char *symlink = 0; - int addslash = 0; auto void add_part (const char *part, int len); @@ -551,23 +557,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename = "."; else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) filename = ".."; - else + else if (entry->len >= 5) { int size = 1; - if (filename) + char *old; + size = entry->len - 5; + old = filename; + if (filename_alloc) { size += grub_strlen (filename); - grub_realloc (filename, - grub_strlen (filename) - + entry->len); + filename = grub_realloc (filename, size + 1); } else { - size = entry->len - 5; + filename_alloc = 1; filename = grub_zalloc (size + 1); + filename[0] = 0; + } + if (!filename) + { + filename = old; + return grub_errno; } filename_alloc = 1; - grub_strncpy (filename, (char *) &entry->data[1], size); + grub_strncat (filename, (char *) &entry->data[1], size); filename[size] = '\0'; } } @@ -601,12 +614,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* The symlink is not stored as a POSIX symlink, translate it. */ while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len)) { - if (addslash) - { - add_part ("/", 1); - addslash = 0; - } - /* The current position is the `Component Flag'. */ switch (entry->data[pos] & 30) { @@ -615,10 +622,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* The data on pos + 2 is the actual data, pos + 1 is the length. Both are part of the `Component Record'. */ + if (symlink && (entry->data[pos] & 1)) + add_part ("/", 1); add_part ((char *) &entry->data[pos + 2], entry->data[pos + 1]); - if ((entry->data[pos] & 1)) - addslash = 1; break; } @@ -653,7 +660,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, for (; offset < len; offset += dirent.len) { symlink = 0; - addslash = 0; if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; From 19ee298767b7780618ea04cb556cd6211fffe780 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 23:06:25 +0100 Subject: [PATCH 132/315] Handle symlinks and long names on tar and cpio. * grub-core/fs/cpio.c (ATTR_TYPE): New definition. (ATTR_FILE): Likewise. (ATTR_DIR): Likewise. (ATTR_LNK): Likewise. (grub_cpio_data) [MODE_USTAR]: New fields linkname and linkname_alloc. (grub_cpio_find_file): Fill mode, handle linkname field as well as L and K entries. (grub_cpio_mount): Zero-fill data. (handle_symlink): New function. --- ChangeLog | 14 ++ grub-core/fs/cpio.c | 351 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 307 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 223afb1e6..543823e9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-10-30 Vladimir Serbinenko + + Handle symlinks and long names on tar and cpio. + + * grub-core/fs/cpio.c (ATTR_TYPE): New definition. + (ATTR_FILE): Likewise. + (ATTR_DIR): Likewise. + (ATTR_LNK): Likewise. + (grub_cpio_data) [MODE_USTAR]: New fields linkname and linkname_alloc. + (grub_cpio_find_file): Fill mode, handle linkname field as well as + L and K entries. + (grub_cpio_mount): Zero-fill data. + (handle_symlink): New function. + 2011-10-30 Vladimir Serbinenko Fix iso9660 filename limitations and fix memory leaks. diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 92531390e..b43e54ec9 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -25,6 +25,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define ATTR_TYPE 0160000 +#define ATTR_FILE 0100000 +#define ATTR_DIR 0040000 +#define ATTR_LNK 0120000 + #ifndef MODE_USTAR /* cpio support */ #define MAGIC_BCPIO 070707 @@ -74,6 +79,10 @@ struct grub_cpio_data grub_off_t hofs; grub_off_t dofs; grub_off_t size; +#ifdef MODE_USTAR + char *linkname; + grub_size_t linkname_alloc; +#endif }; static grub_dl_t my_mod; @@ -101,7 +110,8 @@ canonicalize (char *name) static grub_err_t grub_cpio_find_file (struct grub_cpio_data *data, char **name, - grub_int32_t *mtime, grub_disk_addr_t * ofs) + grub_int32_t *mtime, grub_disk_addr_t *ofs, + grub_uint32_t *mode) { #ifndef MODE_USTAR struct head hd; @@ -115,11 +125,14 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; if (mtime) *mtime = (((grub_uint32_t) hd.mtime_1) << 16) + hd.mtime_2; + if (mode) + *mode = hd.mode; if (hd.namesize & 1) hd.namesize++; - if ((*name = grub_malloc (hd.namesize)) == NULL) + *name = grub_malloc (hd.namesize + 1); + if (*name == NULL) return grub_errno; if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), @@ -128,9 +141,10 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, grub_free (*name); return grub_errno; } + (*name)[hd.namesize] = 0; if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 - && ! grub_memcmp(*name, "TRAILER!!!", 11)) + && grub_memcmp(*name, "TRAILER!!!", 11) == 0) { *ofs = 0; return GRUB_ERR_NONE; @@ -144,29 +158,118 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, (*ofs)++; #else struct head hd; + int reread = 0, have_longname = 0, have_longlink = 0; - if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; - - if (!hd.name[0]) + for (reread = 0; reread < 3; reread++) { - *ofs = 0; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; + + if (!hd.name[0]) + { + *ofs = 0; + return GRUB_ERR_NONE; + } + + if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); + + if (hd.typeflag == 'L') + { + grub_err_t err; + grub_size_t namesize = grub_strtoull (hd.size, NULL, 8); + *name = grub_malloc (namesize + 1); + if (*name == NULL) + return grub_errno; + err = grub_disk_read (data->disk, 0, + data->hofs + GRUB_DISK_SECTOR_SIZE, namesize, + *name); + (*name)[namesize] = 0; + if (err) + return err; + data->hofs += GRUB_DISK_SECTOR_SIZE + + ((namesize + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + have_longname = 1; + continue; + } + + if (hd.typeflag == 'K') + { + grub_err_t err; + grub_size_t linksize = grub_strtoull (hd.size, NULL, 8); + if (data->linkname_alloc < linksize + 1) + { + char *n; + n = grub_malloc (2 * (linksize + 1)); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; + data->linkname_alloc = 2 * (linksize + 1); + } + + err = grub_disk_read (data->disk, 0, + data->hofs + GRUB_DISK_SECTOR_SIZE, linksize, + data->linkname); + if (err) + return err; + data->linkname[linksize] = 0; + data->hofs += GRUB_DISK_SECTOR_SIZE + + ((linksize + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + have_longlink = 1; + continue; + } + + if (!have_longname) + { + *name = grub_strdup (hd.name); + if (*name == NULL) + return grub_errno; + } + + data->size = grub_strtoull (hd.size, NULL, 8); + data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; + *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + if (mtime) + *mtime = grub_strtoul (hd.mtime, NULL, 8); + if (mode) + { + *mode = grub_strtoul (hd.mode, NULL, 8); + switch (hd.typeflag) + { + case '2': + *mode |= ATTR_LNK; + break; + case '0': + *mode |= ATTR_FILE; + break; + case '5': + *mode |= ATTR_DIR; + break; + } + } + if (!have_longlink) + { + if (data->linkname_alloc < 101) + { + char *n; + n = grub_malloc (101); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; + data->linkname_alloc = 101; + } + grub_memcpy (data->linkname, hd.linkname, sizeof (hd.linkname)); + data->linkname[100] = 0; + } + + canonicalize (*name); return GRUB_ERR_NONE; } - - if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - - if ((*name = grub_strdup (hd.name)) == NULL) - return grub_errno; - - data->size = grub_strtoull (hd.size, NULL, 8); - data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; - *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & - ~(GRUB_DISK_SECTOR_SIZE - 1)); - if (mtime) - *mtime = grub_strtoul (hd.mtime, NULL, 8); - canonicalize (*name); #endif return GRUB_ERR_NONE; } @@ -188,7 +291,7 @@ grub_cpio_mount (grub_disk_t disk) #endif goto fail; - data = (struct grub_cpio_data *) grub_malloc (sizeof (*data)); + data = (struct grub_cpio_data *) grub_zalloc (sizeof (*data)); if (!data) goto fail; @@ -208,15 +311,105 @@ fail: } static grub_err_t -grub_cpio_dir (grub_device_t device, const char *path, +handle_symlink (struct grub_cpio_data *data, + const char *fn, char **name, + grub_uint32_t mode, int *restart) +{ + grub_size_t flen; + char *target; +#ifndef MODE_USTAR + grub_err_t err; +#endif + char *ptr; + char *lastslash; + grub_size_t prefixlen; + char *rest; + grub_size_t size; + + *restart = 0; + + if ((mode & ATTR_TYPE) != ATTR_LNK) + return GRUB_ERR_NONE; + flen = grub_strlen (fn); + if (grub_memcmp (*name, fn, flen) != 0 + || ((*name)[flen] != 0 && (*name)[flen] != '/')) + return GRUB_ERR_NONE; + rest = *name + flen; + lastslash = rest; + if (*rest) + rest++; + while (lastslash >= *name && *lastslash != '/') + lastslash--; + if (lastslash >= *name) + prefixlen = lastslash - *name; + else + prefixlen = 0; + + if (prefixlen) + prefixlen++; + +#ifdef MODE_USTAR + size = grub_strlen (data->linkname); +#else + size = data->size; +#endif + if (size == 0) + return GRUB_ERR_NONE; + target = grub_malloc (size + grub_strlen (*name) + 2); + if (!target) + return grub_errno; + +#ifdef MODE_USTAR + grub_memcpy (target + prefixlen, data->linkname, size); +#else + err = grub_disk_read (data->disk, 0, data->dofs, data->size, + target + prefixlen); + if (err) + return err; +#endif + if (target[prefixlen] == '/') + { + grub_memmove (target, target + prefixlen, data->size - 1); + ptr = target + data->size - 1; + ptr = grub_stpcpy (ptr, rest); + *ptr = 0; + grub_dprintf ("cpio", "symlink redirected %s to %s\n", + *name, target); + grub_free (*name); + *name = target; + *restart = 1; + return GRUB_ERR_NONE; + } + if (prefixlen) + { + grub_memcpy (target, *name, prefixlen); + target[prefixlen] = '/'; + } + ptr = target + prefixlen + size; + ptr = grub_stpcpy (ptr, rest); + *ptr = 0; + grub_dprintf ("cpio", "symlink redirected %s to %s\n", + *name, target); + grub_free (*name); + *name = target; + *restart = 1; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cpio_dir (grub_device_t device, const char *path_in, int (*hook) (const char *filename, const struct grub_dirhook_info *info)) { struct grub_cpio_data *data; grub_disk_addr_t ofs; - char *prev, *name; - const char *np; + char *prev, *name, *path; grub_size_t len; + int symlinknest = 0; + + path = grub_strdup (path_in + 1); + if (!path) + return grub_errno; grub_dl_ref (my_mod); @@ -224,23 +417,27 @@ grub_cpio_dir (grub_device_t device, const char *path, data = grub_cpio_mount (device->disk); if (!data) - goto fail; - - np = path + 1; - len = grub_strlen (path) - 1; + { + grub_free (path); + return grub_errno; + } + len = grub_strlen (path); data->hofs = 0; while (1) { grub_int32_t mtime; + grub_uint32_t mode; + grub_err_t err; - if (grub_cpio_find_file (data, &name, &mtime, &ofs)) + if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode)) goto fail; if (!ofs) break; - if (grub_memcmp (np, name, len) == 0) + if (grub_memcmp (path, name, len) == 0 + && (name[len] == 0 || name[len] == '/' || len == 0)) { char *p, *n; @@ -265,14 +462,35 @@ grub_cpio_dir (grub_device_t device, const char *path, prev = name; } else - grub_free (name); + { + int restart; + err = handle_symlink (data, name, &path, mode, &restart); + grub_free (name); + if (err) + goto fail; + if (restart) + { + len = grub_strlen (path); + if (++symlinknest == 8) + { + grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + goto fail; + } + ofs = 0; + } + } } data->hofs = ofs; } fail: + grub_free (path); grub_free (prev); +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif grub_free (data); grub_dl_unref (my_mod); @@ -281,23 +499,33 @@ fail: } static grub_err_t -grub_cpio_open (grub_file_t file, const char *name) +grub_cpio_open (grub_file_t file, const char *name_in) { struct grub_cpio_data *data; grub_disk_addr_t ofs; char *fn; - int i, j; + char *name = grub_strdup (name_in + 1); + int symlinknest = 0; + + if (!name) + return grub_errno; grub_dl_ref (my_mod); data = grub_cpio_mount (file->device->disk); if (!data) - goto fail; + { + grub_free (name); + return grub_errno; + } data->hofs = 0; while (1) { - if (grub_cpio_find_file (data, &fn, NULL, &ofs)) + grub_uint32_t mode; + int restart; + + if (grub_cpio_find_file (data, &fn, NULL, &ofs, &mode)) goto fail; if (!ofs) @@ -306,33 +534,31 @@ grub_cpio_open (grub_file_t file, const char *name) break; } - /* Compare NAME and FN by hand in order to cope with duplicate - slashes. */ - i = 0; - j = 0; - while (name[i] == '/') - i++; - while (1) + if (handle_symlink (data, fn, &name, mode, &restart)) { - if (name[i] != fn[j]) - goto no_match; - - if (name[i] == '\0') - break; - - while (name[i] == '/' && name[i+1] == '/') - i++; - - i++; - j++; + grub_free (fn); + goto fail; } - if (name[i] != fn[j]) + if (restart) + { + ofs = 0; + if (++symlinknest == 8) + { + grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + goto fail; + } + goto no_match; + } + + if (grub_strcmp (name, fn) != 0) goto no_match; file->data = data; file->size = data->size; grub_free (fn); + grub_free (name); return GRUB_ERR_NONE; @@ -343,8 +569,11 @@ grub_cpio_open (grub_file_t file, const char *name) } fail: - +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif grub_free (data); + grub_free (name); grub_dl_unref (my_mod); @@ -364,7 +593,13 @@ grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_cpio_close (grub_file_t file) { - grub_free (file->data); + struct grub_cpio_data *data; + + data = file->data; +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif + grub_free (data); grub_dl_unref (my_mod); From 46bc1dc244f7e6461cc2d59f41a2181722c6c384 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:40:30 +0100 Subject: [PATCH 133/315] * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of long symlinks. --- ChangeLog | 8 ++++++++ grub-core/fs/ufs.c | 13 ++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 543823e9c..825524c09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-31 Vladimir Serbinenko + + * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of + long symlinks. + 2011-10-30 Vladimir Serbinenko Handle symlinks and long names on tar and cpio. @@ -11,6 +16,9 @@ L and K entries. (grub_cpio_mount): Zero-fill data. (handle_symlink): New function. + (grub_cpio_dir): Handle symlinks. + (grub_cpio_open): Likewise. + (grub_cpio_close) [MODE_USTAR]: Free linkname. 2011-10-30 Vladimir Serbinenko diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 435fec6a5..ea7a7455f 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -394,21 +394,16 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) static grub_err_t grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) { - char symlink[INODE_SIZE (data)]; + char symlink[INODE_SIZE (data) + 1]; if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT) return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - if (INODE_NBLOCKS (data) == 0) + if (INODE_SIZE (data) <= sizeof (data->inode.symlink)) grub_strcpy (symlink, (char *) INODE (data, symlink)); else - { - grub_disk_read (data->disk, - (INODE_DIRBLOCKS (data, 0) - << grub_le_to_cpu32 (data->sblock.log2_blksz)), - 0, INODE_SIZE (data), symlink); - symlink[INODE_SIZE (data)] = '\0'; - } + grub_ufs_read_file (data, 0, 0, INODE_SIZE (data), symlink); + symlink[INODE_SIZE (data)] = '\0'; /* The symlink is an absolute path, go back to the root inode. */ if (symlink[0] == '/') From 87661123b23d12bed46d90c3d6c11af7780beb88 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:50:43 +0100 Subject: [PATCH 134/315] Use shifts in UFS. * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro. (grub_ufs_data): New field log2_blksz. (grub_ufs_read_file): Use shifts. (grub_ufs_mount): Check block size and logarithm it. --- ChangeLog | 9 +++++++++ grub-core/fs/ufs.c | 23 ++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 825524c09..79b930c1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-31 Vladimir Serbinenko + + Use shifts in UFS. + + * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro. + (grub_ufs_data): New field log2_blksz. + (grub_ufs_read_file): Use shifts. + (grub_ufs_mount): Check block size and logarithm it. + 2011-10-31 Vladimir Serbinenko * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index ea7a7455f..bfcb7148f 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -50,6 +50,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* Calculate in which group the inode can be found. */ #define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize)) +#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz) #define INODE(data,field) data->inode. field #ifdef MODE_UFS2 @@ -214,6 +215,7 @@ struct grub_ufs_data struct grub_ufs_inode inode; int ino; int linknest; + int log2_blksz; }; static grub_dl_t my_mod; @@ -295,10 +297,9 @@ grub_ufs_read_file (struct grub_ufs_data *data, if (len + pos > INODE_SIZE (data)) len = INODE_SIZE (data) - pos; - blockcnt = grub_divmod64 ((len + pos + UFS_BLKSZ (sblock) - 1), - UFS_BLKSZ (sblock), 0); + blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) >> UFS_LOG_BLKSZ (sblock); - for (i = grub_divmod64 (pos, UFS_BLKSZ (sblock), 0); i < blockcnt; i++) + for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++) { grub_disk_addr_t blknr; grub_off_t blockoff; @@ -306,7 +307,7 @@ grub_ufs_read_file (struct grub_ufs_data *data, int skipfirst = 0; - grub_divmod64 (pos, UFS_BLKSZ (sblock), &blockoff); + blockoff = pos & (UFS_BLKSZ (sblock) - 1); blknr = grub_ufs_get_file_block (data, i); if (grub_errno) @@ -315,14 +316,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* Last block. */ if (i == blockcnt - 1) { - grub_divmod64 (len + pos, UFS_BLKSZ (sblock), &blockend); + blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1); if (!blockend) blockend = UFS_BLKSZ (sblock); } /* First block. */ - if (i == grub_divmod64 (pos, UFS_BLKSZ (sblock), 0)) + if (i == (pos >> UFS_LOG_BLKSZ (sblock))) { skipfirst = blockoff; blockend -= skipfirst; @@ -536,8 +537,16 @@ grub_ufs_mount (grub_disk_t disk) if (grub_errno) goto fail; - if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC) + /* No need to byteswap bsize in this check. It works the same on both + endiannesses. */ + if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC + && data->sblock.bsize != 0 + && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0)) { + for (data->log2_blksz = 0; + (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize); + data->log2_blksz++); + data->disk = disk; data->linknest = 0; return data; From ce109e843cd605acc2e69a1449b723a8edc6c873 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:52:39 +0100 Subject: [PATCH 135/315] Read label on UFS1. * grub-core/fs/ufs.c (grub_ufs_label): Remove MODE_UFS2 condition. (grub_ufs_fs): Always set .label. --- ChangeLog | 7 +++++++ grub-core/fs/ufs.c | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79b930c1e..211a5f9ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-31 Vladimir Serbinenko + + Read label on UFS1. + + * grub-core/fs/ufs.c (grub_ufs_label): Remove MODE_UFS2 condition. + (grub_ufs_fs): Always set .label. + 2011-10-31 Vladimir Serbinenko Use shifts in UFS. diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index bfcb7148f..e951d6ce3 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -705,8 +705,6 @@ grub_ufs_close (grub_file_t file) return GRUB_ERR_NONE; } - -#ifdef MODE_UFS2 static grub_err_t grub_ufs_label (grub_device_t device, char **label) { @@ -726,7 +724,6 @@ grub_ufs_label (grub_device_t device, char **label) return grub_errno; } -#endif static grub_err_t grub_ufs_uuid (grub_device_t device, char **uuid) @@ -790,9 +787,7 @@ static struct grub_fs grub_ufs_fs = .open = grub_ufs_open, .read = grub_ufs_read, .close = grub_ufs_close, -#ifdef MODE_UFS2 .label = grub_ufs_label, -#endif .uuid = grub_ufs_uuid, .mtime = grub_ufs_mtime, .next = 0 From 7c01e783dcff1365057ea917e9095a2cb7b9d271 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 13:56:52 +0100 Subject: [PATCH 136/315] * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and don't report potentially unavialiable fields in debug output. (find_path): Fix double-free and memory leak. --- ChangeLog | 6 ++++++ grub-core/fs/btrfs.c | 17 +++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 211a5f9ca..27c18655a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-31 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and + don't report potentially unavialiable fields in debug output. + (find_path): Fix double-free and memory leak. + 2011-10-31 Vladimir Serbinenko Read label on UFS1. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 93642f789..16e034661 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -992,6 +992,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_error (GRUB_ERR_BAD_FS, "extent not found"); return -1; } + if ((grub_ssize_t) elemsize < ((char *) &data->extent->inl + - (char *) data->extent)) + { + grub_error (GRUB_ERR_BAD_FS, "extent descriptor is too short"); + return -1; + } data->extstart = grub_le_to_cpu64 (key_out.offset); data->extsize = elemsize; data->extent = grub_malloc (elemsize); @@ -1012,12 +1018,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, data->extend = data->extstart + grub_le_to_cpu64 (data->extent->filled); - grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T " (0x%" - PRIxGRUB_UINT64_T ")\n", + grub_dprintf ("btrfs", "regular extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (data->extent->size), - grub_le_to_cpu64 (data->extent->filled)); + grub_le_to_cpu64 (data->extent->size)); if (data->extend <= pos) { grub_error (GRUB_ERR_BAD_FS, "extent not found"); @@ -1309,7 +1313,6 @@ find_path (struct grub_btrfs_data *data, grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, grub_strlen (path) + 1); grub_free (path_alloc); - grub_free (origpath); path = path_alloc = tmp; if (path[0] == '/') { @@ -1385,6 +1388,8 @@ find_path (struct grub_btrfs_data *data, } grub_free (direl); + grub_free (origpath); + grub_free (path_alloc); return GRUB_ERR_NONE; } From ce8ca56ed996ddeff86141f40a2d09dd8046d5c3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 1 Nov 2011 20:05:28 +0100 Subject: [PATCH 137/315] Fix RAIDZ(2). * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member ashift. (fill_vdev_info_real): Set ashift. (read_device): Rewrite RAIDZ part based on reverse engineering. --- ChangeLog | 8 +++++ grub-core/fs/zfs/zfs.c | 70 +++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27c18655a..e112868f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-01 Vladimir Serbinenko + + Fix RAIDZ(2). + + * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member ashift. + (fill_vdev_info_real): Set ashift. + (read_device): Rewrite RAIDZ part based on reverse engineering. + 2011-10-31 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9bd68222a..c7fd13018 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -152,6 +152,7 @@ struct grub_zfs_device_desc /* Valid only for RAIDZ. */ unsigned nparity; + unsigned ashift; /* Valid only for leaf devices. */ grub_device_t dev; @@ -516,6 +517,9 @@ fill_vdev_info_real (struct grub_zfs_data *data, if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); fill->nparity = par; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + fill->ashift = par; } nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); @@ -882,38 +886,76 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, } case DEVICE_RAIDZ: { - grub_uint64_t sector; - grub_uint32_t bsize; unsigned c = 0; + grub_uint64_t high; + grub_uint64_t devn; + grub_uint64_t redundancy_strip = 0, m; + grub_uint64_t redundancy_strip2 = 0; + grub_uint32_t s; - bsize = (asize + desc->nparity) / desc->n_children; - sector = offset >> 9; + /* (4,1) -> 2, (3,1) -> 1 */ + if (desc->nparity == 1) + s = asize + desc->n_children - 2; + else + s = asize + desc->n_children - 3; + high = grub_divmod64 ((offset >> desc->ashift), + desc->n_children, &m); + + if (desc->nparity == 1) + { + redundancy_strip = m; + redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); + if (redundancy_strip == desc->n_children) + redundancy_strip = 0; + redundancy_strip2 = redundancy_strip; + } + else + { + redundancy_strip = m; + redundancy_strip2 = m + 1; + if (redundancy_strip2 == desc->n_children) + redundancy_strip2 = 0; + } + grub_dprintf ("zfs", "rs = %x, %llx\n", + (int) redundancy_strip, + (unsigned long long) high); while (len > 0) { grub_size_t csize; - grub_uint64_t high; - grub_uint64_t devn; + grub_uint32_t bsize; grub_err_t err; - high = grub_divmod64 (sector + (asize > 2) + c, desc->n_children, - &devn); - csize = bsize << 9; + bsize = s / desc->n_children; + + while (1) + { + high = grub_divmod64 ((offset >> desc->ashift) + c, + desc->n_children, &devn); + if (devn != redundancy_strip && devn != redundancy_strip2) + break; + c++; + } + csize = bsize << desc->ashift; if (csize > len) csize = len; + grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T - "+%d+%u -> (0x%" PRIxGRUB_UINT64_T ", 0x%" + "+%u (%d, %d) -> (0x%" PRIxGRUB_UINT64_T ", 0x%" PRIxGRUB_UINT64_T ")\n", - sector,(asize > 2), c, high, devn); - err = read_device (high << 9, &desc->children[devn], + offset >> desc->ashift, c, asize, bsize, high, + devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], bsize, csize, buf); if (err) return err; c++; + s--; buf = (char *) buf + csize; len -= csize; } - return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } From aca5aefc7c7d3a1fccfbd49cb98f360af7e69e93 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Nov 2011 20:48:04 +0100 Subject: [PATCH 138/315] Fix RAIDZ(2) for >= 5 devices. * grub-core/fs/zfs/zfs.c (read_device): Fix length formula. Remove asize argument. All users updated. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfs.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e112868f0..08bad81c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-02 Vladimir Serbinenko + + Fix RAIDZ(2) for >= 5 devices. + + * grub-core/fs/zfs/zfs.c (read_device): Fix length formula. Remove + asize argument. All users updated. + 2011-11-01 Vladimir Serbinenko Fix RAIDZ(2). diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index c7fd13018..1c9b240ab 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -852,7 +852,7 @@ scan_devices (struct grub_zfs_data *data) static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - grub_uint32_t asize, grub_size_t len, void *buf) + grub_size_t len, void *buf) { switch (desc->type) { @@ -876,7 +876,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (offset, &desc->children[i], asize, + err = read_device (offset, &desc->children[i], len, buf); if (!err) break; @@ -893,28 +893,32 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint64_t redundancy_strip2 = 0; grub_uint32_t s; - /* (4,1) -> 2, (3,1) -> 1 */ - if (desc->nparity == 1) - s = asize + desc->n_children - 2; - else - s = asize + desc->n_children - 3; + if (desc->nparity < 1 || desc->nparity > 2) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "raidz%d is not supported", desc->nparity); + + s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) + + (desc->n_children - desc->nparity) - 1); + high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - if (desc->nparity == 1) + + switch (desc->nparity) { + case 1: redundancy_strip = m; redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); if (redundancy_strip == desc->n_children) redundancy_strip = 0; redundancy_strip2 = redundancy_strip; - } - else - { + break; + case 2: redundancy_strip = m; redundancy_strip2 = m + 1; if (redundancy_strip2 == desc->n_children) redundancy_strip2 = 0; + break; } grub_dprintf ("zfs", "rs = %x, %llx\n", (int) redundancy_strip, @@ -924,8 +928,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t csize; grub_uint32_t bsize; grub_err_t err; - bsize = s / desc->n_children; - + bsize = s / (desc->n_children - desc->nparity); + while (1) { high = grub_divmod64 ((offset >> desc->ashift) + c, @@ -934,21 +938,24 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, break; c++; } + csize = bsize << desc->ashift; if (csize > len) csize = len; grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T - "+%u (%d, %d) -> (0x%" PRIxGRUB_UINT64_T ", 0x%" + "+%u (%" PRIxGRUB_SIZE ", %" PRIxGRUB_UINT32_T + ") -> (0x%" PRIxGRUB_UINT64_T ", 0x%" PRIxGRUB_UINT64_T ")\n", - offset >> desc->ashift, c, asize, bsize, high, + offset >> desc->ashift, c, len, bsize, high, devn); err = read_device ((high << desc->ashift) | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], - bsize, csize, buf); + csize, buf); if (err) return err; + c++; s--; buf = (char *) buf + csize; @@ -976,8 +983,7 @@ read_dva (const dva_t *dva, for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) { - err = read_device (offset, &data->devices_attached[i], - dva->dva_word[0] & 0xffffff, len, buf); + err = read_device (offset, &data->devices_attached[i], len, buf); if (!err) return GRUB_ERR_NONE; break; From 177440046d0f5129dfa2513835a42cfb86fdc2c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Nov 2011 23:28:25 +0100 Subject: [PATCH 139/315] * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single drive failure on both raidz and raidz2. --- ChangeLog | 5 +++ grub-core/fs/zfs/zfs.c | 100 +++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08bad81c6..047c156c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-02 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single + drive failure on both raidz and raidz2. + 2011-11-02 Vladimir Serbinenko Fix RAIDZ(2) for >= 5 devices. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1c9b240ab..1bfbed72c 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -850,6 +850,14 @@ scan_devices (struct grub_zfs_data *data) return GRUB_ERR_NONE; } +static inline void +xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s) +{ + s /= sizeof (grub_uint64_t); + while (s--) + *a++ ^= *b++; +} + static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) @@ -889,40 +897,26 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, unsigned c = 0; grub_uint64_t high; grub_uint64_t devn; - grub_uint64_t redundancy_strip = 0, m; - grub_uint64_t redundancy_strip2 = 0; - grub_uint32_t s; + grub_uint64_t m; + grub_uint32_t s, orig_s; + void *orig_buf = buf; + grub_size_t orig_len = len; + void *recovery_buf = NULL; + grub_size_t recovery_len = 0; if (desc->nparity < 1 || desc->nparity > 2) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "raidz%d is not supported", desc->nparity); - s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) - + (desc->n_children - desc->nparity) - 1); + orig_s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) + + (desc->n_children - desc->nparity) - 1); + s = orig_s; high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - - switch (desc->nparity) - { - case 1: - redundancy_strip = m; - redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); - if (redundancy_strip == desc->n_children) - redundancy_strip = 0; - redundancy_strip2 = redundancy_strip; - break; - case 2: - redundancy_strip = m; - redundancy_strip2 = m + 1; - if (redundancy_strip2 == desc->n_children) - redundancy_strip2 = 0; - break; - } - grub_dprintf ("zfs", "rs = %x, %llx\n", - (int) redundancy_strip, - (unsigned long long) high); + if (desc->nparity == 2) + c = 2; while (len > 0) { grub_size_t csize; @@ -930,15 +924,12 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_err_t err; bsize = s / (desc->n_children - desc->nparity); - while (1) - { - high = grub_divmod64 ((offset >> desc->ashift) + c, - desc->n_children, &devn); - if (devn != redundancy_strip && devn != redundancy_strip2) - break; - c++; - } + if (desc->nparity == 1 + && ((offset >> (desc->ashift + 11)) & 1) == c) + c++; + high = grub_divmod64 ((offset >> desc->ashift) + c, + desc->n_children, &devn); csize = bsize << desc->ashift; if (csize > len) csize = len; @@ -953,6 +944,13 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); + /* No raidz2 recovery yet. */ + if (err && recovery_len == 0) + { + recovery_buf = buf; + recovery_len = csize; + grub_errno = err = 0; + } if (err) return err; @@ -961,8 +959,42 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, buf = (char *) buf + csize; len -= csize; } + if (recovery_buf) + { + grub_err_t err; + high = grub_divmod64 ((offset >> desc->ashift) + + + ((desc->nparity == 1) + && ((offset >> (desc->ashift + 11)) & 1)), + desc->n_children, &devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], + recovery_len, recovery_buf); + if (err) + return err; + buf = orig_buf; + len = orig_len; + s = orig_s; + while (len > 0) + { + grub_size_t csize; + csize = ((s / (desc->n_children - desc->nparity)) + << desc->ashift); + if (csize > len) + csize = len; + + if (buf != recovery_buf) + xor (recovery_buf, buf, + csize < recovery_len ? csize : recovery_len); + + s--; + buf = (char *) buf + csize; + len -= csize; + } + } + return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } From cf5ba824ea0d09e43b11af0d36e7267ec323c157 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 07:29:35 +0100 Subject: [PATCH 140/315] * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. --- ChangeLog | 4 ++++ grub-core/fs/zfs/zfs.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 047c156c7..f6f5eaeeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. + 2011-11-02 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1bfbed72c..ef352a770 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -904,7 +904,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, void *recovery_buf = NULL; grub_size_t recovery_len = 0; - if (desc->nparity < 1 || desc->nparity > 2) + if (desc->nparity < 1 || desc->nparity > 3) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "raidz%d is not supported", desc->nparity); @@ -914,9 +914,10 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - if (desc->nparity == 2) c = 2; + if (desc->nparity == 3) + c = 3; while (len > 0) { grub_size_t csize; From f92ece7d45946f04b5dacda73efe99c2df3888c9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 14:52:59 +0100 Subject: [PATCH 141/315] * grub-core/fs/nilfs2.c (grub_nilfs2_mtime): Use correct superblock field. --- grub-core/fs/nilfs2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index a8bbe9566..35a040b97 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -1152,7 +1152,7 @@ grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) if (!data) *tm = 0; else - *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime); + *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_wtime); grub_dl_unref (my_mod); From 7d0ac9316382378b389c15b0d103296df8e640dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 14:57:34 +0100 Subject: [PATCH 142/315] Make reiserfs label retrieval similar to other *_label functions. * grub-core/fs/reiserfs.c (grub_reiserfs_superblock): New field label. (REISERFS_MAX_LABEL_LENGTH): Removed. (REISERFS_LABEL_OFFSET): Likewise. (grub_reiserfs_label): Rewritten. --- ChangeLog | 14 ++++++++++++++ grub-core/fs/reiserfs.c | 25 +++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6f5eaeeb..84ad4f9ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-03 Vladimir Serbinenko + + Make reiserfs label retrieval similar to other *_label functions. + + * grub-core/fs/reiserfs.c (grub_reiserfs_superblock): New field label. + (REISERFS_MAX_LABEL_LENGTH): Removed. + (REISERFS_LABEL_OFFSET): Likewise. + (grub_reiserfs_label): Rewritten. + +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/nilfs2.c (grub_nilfs2_mtime): Use correct superblock + field. + 2011-11-03 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index d5bc52d14..639de8d74 100644 --- a/grub-core/fs/reiserfs.c +++ b/grub-core/fs/reiserfs.c @@ -57,8 +57,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB" /* If the 3rd bit of an item state is set, then it's visible. */ #define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04) -#define REISERFS_MAX_LABEL_LENGTH 16 -#define REISERFS_LABEL_OFFSET 0x64 #define S_IFLNK 0xA000 @@ -109,6 +107,7 @@ struct grub_reiserfs_superblock grub_uint32_t inode_generation; grub_uint8_t unused[4]; grub_uint16_t uuid[8]; + char label[16]; } __attribute__ ((packed)); struct grub_reiserfs_journal_header @@ -1323,14 +1322,24 @@ grub_reiserfs_dir (grub_device_t device, const char *path, static grub_err_t grub_reiserfs_label (grub_device_t device, char **label) { - *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH); - if (*label) + struct grub_reiserfs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_reiserfs_mount (disk); + if (data) { - grub_disk_read (device->disk, - REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE, - REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH, - *label); + *label = grub_strndup (data->superblock.label, + sizeof (data->superblock.label)); } + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + return grub_errno; } From 9d9b3d2f0260a7782dfe5f91e3240cde4cf132ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 15:00:45 +0100 Subject: [PATCH 143/315] * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field as well. --- ChangeLog | 5 +++++ grub-core/fs/ufs.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84ad4f9ec..9ec293dda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field + as well. + 2011-11-03 Vladimir Serbinenko Make reiserfs label retrieval similar to other *_label functions. diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index e951d6ce3..cd2994895 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -761,11 +761,13 @@ grub_ufs_mtime (grub_device_t device, grub_int32_t *tm) if (!data) *tm = 0; else + { + *tm = grub_le_to_cpu32 (data->sblock.mtime); #ifdef MODE_UFS2 - *tm = grub_le_to_cpu64 (data->sblock.mtime2); -#else - *tm = grub_le_to_cpu32 (data->sblock.mtime); + if (*tm < (grub_int64_t) grub_le_to_cpu64 (data->sblock.mtime2)) + *tm = grub_le_to_cpu64 (data->sblock.mtime2); #endif + } grub_dl_unref (my_mod); From 158dc1ea2604c8d9f17ec6c59f90c91760756057 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 15:13:30 +0100 Subject: [PATCH 144/315] XZ CRC64 and SHA256 support. * Makefile.util.def (libgrubmods): Add crc64.c. * grub-core/Makefile.core.def (crc64): New module. * grub-core/lib/crc64.c: New file. * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. Fix the type. (MAX_HASH_SIZE): New define. (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. Handle non-crc32 hashes. (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. (dec_stream_header): Handle non-crc32 hashes. (dec_stream_footer): Likewise. (dec_block_header): Likewise. (dec_main): Likewise. (xz_dec_init): Likewise. (xz_dec_reset): Likewise. (xz_dec_end): Likewise. * util/import_gcry.py: Add CRC64 line. --- ChangeLog | 28 ++ Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/lib/crc64.c | 111 ++++++++ grub-core/lib/xzembed/xz_dec_stream.c | 355 +++++++++++++++++--------- util/import_gcry.py | 1 + 6 files changed, 387 insertions(+), 114 deletions(-) create mode 100644 grub-core/lib/crc64.c diff --git a/ChangeLog b/ChangeLog index 9ec293dda..983b7e9e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-11-03 Vladimir Serbinenko + + XZ CRC64 and SHA256 support. + + * Makefile.util.def (libgrubmods): Add crc64.c. + * grub-core/Makefile.core.def (crc64): New module. + * grub-core/lib/crc64.c: New file. + * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) + [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. + Fix the type. + (MAX_HASH_SIZE): New define. + (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. + (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. + (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... + (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. + Handle non-crc32 hashes. + (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. + (dec_stream_header): Handle non-crc32 hashes. + (dec_stream_footer): Likewise. + (dec_block_header): Likewise. + (dec_main): Likewise. + (xz_dec_init): Likewise. + (xz_dec_reset): Likewise. + (xz_dec_end): Likewise. + * util/import_gcry.py: Add CRC64 line. + 2011-11-03 Vladimir Serbinenko * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field diff --git a/Makefile.util.def b/Makefile.util.def index a839920d5..17894b1d2 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -93,6 +93,7 @@ library = { common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/crc.c; common = grub-core/lib/adler32.c; + common = grub-core/lib/crc64.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2b72d8429..b2e8e7aa2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1698,3 +1698,8 @@ module = { name = adler32; common = lib/adler32.c; }; + +module = { + name = crc64; + common = lib/crc64.c; +}; diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c new file mode 100644 index 000000000..92c398d1e --- /dev/null +++ b/grub-core/lib/crc64.c @@ -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 . + */ + +#include +#include +#include + +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); +} diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 3bf201d50..383c29a2f 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -32,10 +32,13 @@ struct xz_dec_hash { vli_type unpadded; vli_type uncompressed; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *crc32_context; + uint64_t *hash_context; #endif }; +/* Enough for up to 512 bits. */ +#define MAX_HASH_SIZE 64 + struct xz_dec { /* Position in dec_main() */ enum { @@ -62,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; +#endif + grub_size_t hash_size; + grub_uint8_t hash_id; /* True if we are operating in single-call mode. */ bool single_call; @@ -250,9 +264,12 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - if (s->has_crc32) - GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start, - b->out_pos - s->out_start); + 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) { @@ -268,14 +285,15 @@ 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; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->block.hash.crc32_context, - (const uint8_t *)&s->block.hash, 2 * sizeof(vli_type)); + 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; @@ -290,7 +308,10 @@ 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; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used); + 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 } @@ -337,8 +358,9 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) s->index.hash.uncompressed += s->vli; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->index.hash.crc32_context, - (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); + 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; @@ -354,13 +376,30 @@ 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) { #ifndef GRUB_EMBED_DECOMPRESSOR - if(s->crc32_temp == 0) + 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 @@ -369,23 +408,38 @@ static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) return XZ_OK; #ifndef GRUB_EMBED_DECOMPRESSOR - if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++]) + 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)); #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); + if (s->hash) + s->hash->init(s->hash_context); + if (s->crc32) + s->crc32->init(s->crc32_context); #endif - s->crc32_temp = 0; + s->have_hash_value = 0; s->pos = 0; return XZ_STREAM_END; } +#ifndef GRUB_EMBED_DECOMPRESSOR +static struct +{ + const char *name; + grub_size_t size; +} hashes[] = { + [0x01] = { "CRC32", 4}, + [0x04] = { "CRC64", 8}, + [0x0A] = { "SHA256", 32}, +}; +#endif + /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ static enum xz_ret dec_stream_header(struct xz_dec *s) { @@ -393,17 +447,27 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) return XZ_FORMAT_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + 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 /* @@ -411,10 +475,77 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) * only none (Check ID = 0) and CRC32 (Check ID = 1). */ 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]; + +#ifndef GRUB_EMBED_DECOMPRESSOR + 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); + } +#else + s->hash = 0; +#endif +#if 1 + if (!s->hash) + return XZ_OPTIONS_ERROR; +#endif + } + else + { + s->hash = 0; + s->hash_size = 0; + } + + s->have_hash_value = 0; + return XZ_OK; } @@ -426,19 +557,30 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + 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(resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif + /* * Validate Backward Size. Note that we never added the size of the * Index CRC32 field to s->index.size, thus we use s->index.size / 4 @@ -447,7 +589,7 @@ 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) + if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id) return XZ_DATA_ERROR; /* @@ -468,17 +610,27 @@ static enum xz_ret dec_block_header(struct xz_dec *s) */ s->temp.size -= 4; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + 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, s->temp.size); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf, s->temp.size); + 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 + s->temp.size); + 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]; - 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; @@ -659,11 +811,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; @@ -691,24 +841,31 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) index_update(s, b); #ifndef GRUB_EMBED_DECOMPRESSOR - /* 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) + 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; @@ -802,46 +959,12 @@ struct xz_dec * xz_dec_init(uint32_t dict_max) return NULL; #endif + memset (s, 0, sizeof (*s)); + #ifndef GRUB_EMBED_DECOMPRESSOR - /* 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); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + s->crc32 = grub_crypto_lookup_md_by_name ("CRC32"); #endif - s->crc32_temp = 0; - s->single_call = dict_max == 0; #ifdef XZ_DEC_BCJ @@ -876,28 +999,31 @@ void xz_dec_reset(struct xz_dec *s) { #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *t; - t = s->block.hash.crc32_context; + uint64_t *t; + t = s->block.hash.hash_context; #endif memzero(&s->block, sizeof(s->block)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->block.hash.crc32_context = t; - t = s->index.hash.crc32_context; + s->block.hash.hash_context = t; + t = s->index.hash.hash_context; #endif memzero(&s->index, sizeof(s->index)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->index.hash.crc32_context = t; + s->index.hash.hash_context = t; #endif } s->temp.pos = 0; s->temp.size = STREAM_HEADER_SIZE; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + 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->crc32_temp = 0; + s->have_hash_value = 0; } void xz_dec_end(struct xz_dec *s) @@ -905,8 +1031,9 @@ void xz_dec_end(struct xz_dec *s) if (s != NULL) { xz_dec_lzma2_end(s->lzma2); #ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s->index.hash.crc32_context); - kfree(s->block.hash.crc32_context); + 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 diff --git a/util/import_gcry.py b/util/import_gcry.py index 7591d8f0e..ec34d16b5 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -83,6 +83,7 @@ cryptolist.write ("AES-192: gcry_rijndael\n"); cryptolist.write ("AES-256: gcry_rijndael\n"); cryptolist.write ("ADLER32: adler32\n"); +cryptolist.write ("CRC64: crc64\n"); for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file) From 9cc3581d7d06d3d56a1e1b54316bef66362513f5 Mon Sep 17 00:00:00 2001 From: crocket Date: Thu, 3 Nov 2011 15:21:47 +0100 Subject: [PATCH 145/315] * util/grub.d/10_linux.in: Add Slackware initrd naming. --- ChangeLog | 4 ++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 983b7e9e5..81f5d942d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 crocket + + * util/grub.d/10_linux.in: Add Slackware initrd naming. + 2011-11-03 Vladimir Serbinenko XZ CRC64 and SHA256 support. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index c3565096b..fe4f0e730 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -156,7 +156,7 @@ while [ "x$list" != "x" ] ; do linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" initrd= - for i in "initrd.img-${version}" "initrd-${version}.img" \ + for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ "initrd-${version}" "initramfs-${version}.img" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img" \ From 1e51cabd7bf407917363d24fbe53c44ee0e925bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 16:04:26 +0100 Subject: [PATCH 146/315] * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is NULL. --- ChangeLog | 5 +++++ grub-core/gettext/gettext.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81f5d942d..ceca3fddb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is + NULL. + 2011-11-03 crocket * util/grub.d/10_linux.in: Add Slackware initrd naming. diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index cca8b901f..8581b1ff3 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -296,6 +296,9 @@ grub_gettext_init_ext (const char *locale) { char *locale_dir; + if (!locale) + return; + locale_dir = grub_env_get ("locale_dir"); if (locale_dir == NULL) { @@ -370,8 +373,6 @@ grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)), GRUB_MOD_INIT (gettext) { - (void) mod; /* To stop warning. */ - const char *lang; lang = grub_env_get ("lang"); From 182c872a7bedb2c2c228cbee1e7022616aa8416b Mon Sep 17 00:00:00 2001 From: Philipp Matthias Hahn Date: Thu, 3 Nov 2011 16:49:02 +0100 Subject: [PATCH 147/315] * util/grub-mkrescue.in: Fix handling xorriso option. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ceca3fddb..028bffe5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 Philipp Matthias Hahn + + * util/grub-mkrescue.in: Fix handling xorriso option. + 2011-11-03 Vladimir Serbinenko * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4c96dd42b..eff77088f 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -129,7 +129,7 @@ do --xorriso) xorriso=`argument $option "$@"`; shift ;; --xorriso=*) - xorriso=`echo "${option}/" | sed 's/--xorriso=//'` ;; + xorriso=`echo "${option}" | sed 's/--xorriso=//'` ;; *) source="${source} ${option} $@"; break ;; From dbd3a32e4325699e997de191b9c265c301a888bd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:15:29 +0100 Subject: [PATCH 148/315] * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole disk. * grub-core/disk/lvm.c (do_lvm_scan): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/lvm.c | 4 ++-- grub-core/disk/raid.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 028bffe5c..89974cff6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-04 Vladimir Serbinenko + + * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole + disk. + * grub-core/disk/lvm.c (do_lvm_scan): Likewise. + 2011-11-03 Philipp Matthias Hahn * util/grub-mkrescue.in: Fix handling xorriso option. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 7c65db4ab..4020fc427 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -157,8 +157,8 @@ do_lvm_scan (const char *scan_for) && pv->disk->dev->id == disk->dev->id && grub_partition_get_start (pv->disk->partition) == grub_partition_get_start (disk->partition) - && grub_partition_get_len (pv->disk->partition) - == grub_partition_get_len (disk->partition)) + && grub_disk_get_size (pv->disk) + == grub_disk_get_size (disk)) { grub_disk_close (disk); return 0; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 07249eabc..e4c53e73b 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -123,8 +123,8 @@ scan_devices (const char *arname) && m->device->dev->id == m->device->dev->id && grub_partition_get_start (m->device->partition) == grub_partition_get_start (disk->partition) - && grub_partition_get_len (m->device->partition) - == grub_partition_get_len (disk->partition)) + && grub_disk_get_size (m->device) + == grub_disk_get_size (disk)) { grub_disk_close (disk); return 0; From 8bec9a284bf2bc3f492fc1ba62b0f199998f81b2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:18:30 +0100 Subject: [PATCH 149/315] * include/grub/kernel.h (grub_module_header): Make type into uint32 as expected by grub-mkimage and it's more clear since there is no implicit padding. --- ChangeLog | 6 ++++++ include/grub/kernel.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 89974cff6..52bd2608d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-04 Vladimir Serbinenko + + * include/grub/kernel.h (grub_module_header): Make type into uint32 as + expected by grub-mkimage and it's more clear since there is no implicit + padding. + 2011-11-04 Vladimir Serbinenko * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 2ff6b2469..f9fc817db 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -34,7 +34,7 @@ enum struct grub_module_header { /* The type of object. */ - grub_uint8_t type; + grub_uint32_t type; /* The size of object (including this header). */ grub_uint32_t size; }; From 09e2763fb150684377d0633f0de92591f4dbe93b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:22:38 +0100 Subject: [PATCH 150/315] * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector for the right device. --- ChangeLog | 5 +++++ grub-core/disk/raid6_recover.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52bd2608d..f8813f259 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-04 Vladimir Serbinenko + + * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector + for the right device. + 2011-11-04 Vladimir Serbinenko * include/grub/kernel.h (grub_module_header): Make type into uint32 as diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 25b50eb6b..54dc612ee 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -122,7 +122,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, { if ((array->members[pos].device) && (! grub_disk_read (array->members[pos].device, - array->members[i].start_sector + sector, + array->members[pos].start_sector + sector, 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); @@ -154,7 +154,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, /* One bad device */ if ((array->members[p].device) && (! grub_disk_read (array->members[p].device, - array->members[i].start_sector + sector, + array->members[p].start_sector + sector, 0, size, buf))) { grub_raid_block_xor (buf, pbuf, size); @@ -169,7 +169,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, grub_errno = GRUB_ERR_NONE; if (grub_disk_read (array->members[q].device, - array->members[i].start_sector + sector, 0, size, buf)) + array->members[q].start_sector + sector, 0, size, buf)) goto quit; grub_raid_block_xor (buf, qbuf, size); @@ -188,14 +188,14 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, } if (grub_disk_read (array->members[p].device, - array->members[i].start_sector + sector, + array->members[p].start_sector + sector, 0, size, buf)) goto quit; grub_raid_block_xor (pbuf, buf, size); if (grub_disk_read (array->members[q].device, - array->members[i].start_sector + sector, + array->members[q].start_sector + sector, 0, size, buf)) goto quit; From 11ee4389e27c9e776d598bc90f452cd3918982ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:27:50 +0100 Subject: [PATCH 151/315] Use a power of generator representation of GF(256) multiplication group to save space time and complexity. * grub-core/disk/raid6_recover.c (raid6_table1): Removed. (raid6_table2): Likewise. (powx): New array. (powx_inv): Likewise. (poly): New const. (grub_raid_block_mul): Replace with ... (grub_raid_block_mulx): ...this. (grub_raid6_init_table): Rewritten. (grub_raid6_recover): Use power of generator representation. --- ChangeLog | 15 +++++++ grub-core/disk/raid6_recover.c | 81 ++++++++++++---------------------- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8813f259..b9e32f0e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-11-04 Vladimir Serbinenko + + Use a power of generator representation of GF(256) multiplication group + to save space time and complexity. + + * grub-core/disk/raid6_recover.c (raid6_table1): Removed. + (raid6_table2): Likewise. + (powx): New array. + (powx_inv): Likewise. + (poly): New const. + (grub_raid_block_mul): Replace with ... + (grub_raid_block_mulx): ...this. + (grub_raid6_init_table): Rewritten. + (grub_raid6_recover): Use power of generator representation. + 2011-11-04 Vladimir Serbinenko * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 54dc612ee..e91992547 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -26,67 +26,40 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_uint8_t raid6_table1[256][256]; -static grub_uint8_t raid6_table2[256][256]; +/* x**y. */ +static grub_uint8_t powx[255 * 2]; +/* Such an s that x**s = y */ +static int powx_inv[256]; +static const grub_uint8_t poly = 0x1d; static void -grub_raid_block_mul (grub_uint8_t mul, char *buf, int size) +grub_raid_block_mulx (int mul, char *buf, int size) { int i; grub_uint8_t *p; p = (grub_uint8_t *) buf; for (i = 0; i < size; i++, p++) - *p = raid6_table1[mul][*p]; + if (*p) + *p = powx[mul + powx_inv[*p]]; } static void grub_raid6_init_table (void) { - int i, j; + int i; - for (i = 0; i < 256; i++) - raid6_table1[i][1] = raid6_table1[1][i] = i; - - for (i = 2; i < 256; i++) - for (j = i; j < 256; j++) - { - int n; - grub_uint8_t c; - - n = i >> 1; - - c = raid6_table1[n][j]; - c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0); - if (i & 1) - c ^= j; - - raid6_table1[j][i] = raid6_table1[i][j] = c; - } - - raid6_table2[0][0] = 1; - for (i = 1; i < 256; i++) - raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2]; - - for (i = 0; i < 254; i++) - for (j = 0; j < 254; j++) - { - grub_uint8_t c, n; - int k; - - if (i == j) - continue; - - k = i - j; - if (k < 0) - k += 255; - - c = n = raid6_table2[k][k] ^ 1; - for (k = 0; k < 253; k++) - c = raid6_table1[c][n]; - - raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c]; - } + grub_uint8_t cur = 1; + for (i = 0; i < 255; i++) + { + powx[i] = cur; + powx[i + 255] = cur; + powx_inv[cur] = i; + if (cur & 0x80) + cur = (cur << 1) ^ poly; + else + cur <<= 1; + } } static grub_err_t @@ -126,7 +99,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); - grub_raid_block_mul (raid6_table2[i][i], buf, size); + grub_raid_block_mulx (i, buf, size); grub_raid_block_xor (qbuf, buf, size); } else @@ -173,13 +146,13 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, goto quit; grub_raid_block_xor (buf, qbuf, size); - grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf, + grub_raid_block_mulx (255 - bad1, buf, size); } else { /* Two bad devices */ - grub_uint8_t c; + int c; if ((! array->members[p].device) || (! array->members[q].device)) { @@ -201,11 +174,11 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, grub_raid_block_xor (qbuf, buf, size); - c = raid6_table2[bad2][bad1]; - grub_raid_block_mul (c, qbuf, size); + c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255; + grub_raid_block_mulx (c, qbuf, size); - c = raid6_table1[raid6_table2[bad2][bad2]][c]; - grub_raid_block_mul (c, pbuf, size); + c = (bad2 + c) % 255; + grub_raid_block_mulx (c, pbuf, size); grub_raid_block_xor (pbuf, qbuf, size); grub_memcpy (buf, pbuf, size); From 95f2e86095d8349af0936a820270ecba972fa636 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:36:08 +0100 Subject: [PATCH 152/315] Support second redundancy strip on raidz(2,3). * grub-core/fs/zfs/zfs.c (powx): New array. (powx_inv): Likewise. (poly): New const. (xor_out): New function. (gf_mul): Likewise. (recovery): Likewise. (read_device): Use second redundancy strip. --- ChangeLog | 12 +++ grub-core/fs/zfs/zfs.c | 208 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 197 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9e32f0e0..a75ec3705 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-11-04 Vladimir Serbinenko + + Support second redundancy strip on raidz(2,3). + + * grub-core/fs/zfs/zfs.c (powx): New array. + (powx_inv): Likewise. + (poly): New const. + (xor_out): New function. + (gf_mul): Likewise. + (recovery): Likewise. + (read_device): Use second redundancy strip. + 2011-11-04 Vladimir Serbinenko Use a power of generator representation of GF(256) multiplication group diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index ef352a770..4c92425dd 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -858,6 +858,92 @@ xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s) *a++ ^= *b++; } +/* x**y. */ +static grub_uint8_t powx[255 * 2]; +/* Such an s that x**s = y */ +static int powx_inv[256]; +static const grub_uint8_t poly = 0x1d; + +/* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */ +static inline void +xor_out (void *a_in, const void *b_in, grub_size_t s, + int known_idx, int recovery_pow) +{ + int add; + grub_uint8_t *a = a_in; + const grub_uint8_t *b = b_in; + + /* Simple xor. */ + if (known_idx == 0 || recovery_pow == 0) + { + xor (a_in, b_in, s); + return; + } + add = (known_idx * recovery_pow) % 255; + for (;s--; b++, a++) + if (*b) + *a ^= powx[powx_inv[*b] + add]; +} + +static inline grub_uint8_t +gf_mul (grub_uint8_t a, grub_uint8_t b) +{ + if (a == 0 || b == 0) + return 0; + return powx[powx_inv[a] + powx_inv[b]]; +} + +static inline void +recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, + const unsigned *powers, + const int *idx) +{ + /* Now we have */ + /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ + /* Since nbufs <= 3 let's be lazy. */ + switch (nbufs) + { + /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])). */ + case 1: + { + int add; + grub_uint8_t *a; + if (powers[0] == 0 || idx[0] == 0) + return; + add = 255 - ((powers[0] * idx[0]) % 255); + for (a = bufs[0]; s--; a++) + if (*a) + *a = powx[powx_inv[*a] + add]; + return; + } + /* b_0 = r_0 * (x ** (powers[0] * idx[0])) + r_1 * (x ** (powers[0] * idx[1])) + b_1 = r_0 * (x ** (powers[1] * idx[0])) + r_1 * (x ** (powers[1] * idx[1])) + */ + case 2: + { + grub_uint8_t det, det_inv; + grub_uint8_t det0, det1; + unsigned i; + /* The determinant is: */ + det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255] + ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]); + det_inv = powx[255 - powx_inv[det]]; + for (i = 0; i < s; i++) + { + det0 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[1]) % 255]) + ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[1]) % 255])); + det1 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[0]) % 255]) + ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[0]) % 255])); + + bufs[0][i] = gf_mul (det0, det_inv); + bufs[1][i] = gf_mul (det1, det_inv); + } + break; + } + } + +} + static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) @@ -901,8 +987,11 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint32_t s, orig_s; void *orig_buf = buf; grub_size_t orig_len = len; - void *recovery_buf = NULL; - grub_size_t recovery_len = 0; + grub_uint8_t *recovery_buf[4]; + grub_size_t recovery_len[4]; + int recovery_idx[4]; + unsigned failed_devices = 0; + int idx, orig_idx; if (desc->nparity < 1 || desc->nparity > 3) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, @@ -918,6 +1007,12 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, c = 2; if (desc->nparity == 3) c = 3; + if (((len + (1 << desc->ashift) - 1) >> desc->ashift) + >= (desc->n_children - desc->nparity)) + idx = (desc->n_children - desc->nparity - 1); + else + idx = ((len + (1 << desc->ashift) - 1) >> desc->ashift) - 1; + orig_idx = idx; while (len > 0) { grub_size_t csize; @@ -945,38 +1040,84 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); - /* No raidz2 recovery yet. */ - if (err && recovery_len == 0) + /* No raidz3 recovery yet. */ + if (err + && failed_devices < desc->nparity + && failed_devices < 2) { - recovery_buf = buf; - recovery_len = csize; + recovery_buf[failed_devices] = buf; + recovery_len[failed_devices] = csize; + recovery_idx[failed_devices] = idx; + failed_devices++; grub_errno = err = 0; } if (err) return err; c++; + idx--; s--; buf = (char *) buf + csize; len -= csize; } - if (recovery_buf) + if (failed_devices) { - grub_err_t err; - high = grub_divmod64 ((offset >> desc->ashift) - + - ((desc->nparity == 1) - && ((offset >> (desc->ashift + 11)) & 1)), - desc->n_children, &devn); - err = read_device ((high << desc->ashift) - | (offset & ((1 << desc->ashift) - 1)), - &desc->children[devn], - recovery_len, recovery_buf); - if (err) - return err; + unsigned redundancy_pow[4]; + unsigned cur_redundancy_pow = 0; + unsigned n_redundancy = 0; + unsigned i, j; + + /* Compute mul. x**s has a period of 255. */ + if (powx[0] == 0) + { + grub_uint8_t cur = 1; + for (i = 0; i < 255; i++) + { + powx[i] = cur; + powx[i + 255] = cur; + powx_inv[cur] = i; + if (cur & 0x80) + cur = (cur << 1) ^ poly; + else + cur <<= 1; + } + } + + /* Read redundancy data. */ + for (n_redundancy = 0, cur_redundancy_pow = 0; + n_redundancy < failed_devices; + cur_redundancy_pow++) + { + grub_err_t err; + high = grub_divmod64 ((offset >> desc->ashift) + + cur_redundancy_pow + + ((desc->nparity == 1) + && ((offset >> (desc->ashift + 11)) + & 1)), + desc->n_children, &devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], + recovery_len[n_redundancy], + recovery_buf[n_redundancy]); + /* Ignore error if we may still have enough devices. */ + if (err && n_redundancy + desc->nparity - cur_redundancy_pow - 1 + >= failed_devices) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + redundancy_pow[n_redundancy] = cur_redundancy_pow; + n_redundancy++; + } + /* Now xor-our the parts we already know. */ buf = orig_buf; len = orig_len; s = orig_s; + idx = orig_idx; + while (len > 0) { grub_size_t csize; @@ -985,14 +1126,35 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, if (csize > len) csize = len; - if (buf != recovery_buf) - xor (recovery_buf, buf, - csize < recovery_len ? csize : recovery_len); + for (j = 0; j < failed_devices; j++) + if (buf == recovery_buf[j]) + break; + + if (j == failed_devices) + for (j = 0; j < failed_devices; j++) + xor_out (recovery_buf[j], buf, + csize < recovery_len[j] ? csize : recovery_len[j], + idx, redundancy_pow[j]); s--; buf = (char *) buf + csize; len -= csize; - } + idx--; + } + for (i = 0; i < failed_devices + && recovery_len[i] == recovery_len[0]; + i++); + /* Since the chunks have variable length handle the last block + separately. */ + if (i != failed_devices) + { + grub_uint8_t *tmp_recovery_buf[4]; + for (j = 0; j < i; j++) + tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[j] - 1; + recovery (tmp_recovery_buf, 1, i, redundancy_pow, recovery_idx); + } + recovery (recovery_buf, recovery_len[failed_devices - 1], + failed_devices, redundancy_pow, recovery_idx); } return GRUB_ERR_NONE; } From 8622923b662282f534ee88307065bc9ded80a023 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:44:56 +0100 Subject: [PATCH 153/315] Support case-insensitive ZFS subvolumes. * grub-core/fs/zfs/zfs.c (mzap_lookup): New parameter case_insensitive. All users updated. (zap_hash): Likewise. (name_cmp): New function. (zap_leaf_array_equal): New parameter case_insensitive. All users updated. (zap_leaf_lookup): Likewise. (fzap_lookup): Likewise. (zap_lookup): Likewise. (dnode_get_path): New parameter case_insensitive. Retrieve case sensitiviness of a volume. All users updated. (dnode_get_fullpath): New parameter case_insensitive. All users updated. (grub_zfs_dir): Set info.case_insensitiveness. --- ChangeLog | 19 +++++++ grub-core/fs/zfs/zfs.c | 112 ++++++++++++++++++++++++++++++----------- 2 files changed, 101 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index a75ec3705..48c43467b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-11-04 Vladimir Serbinenko + + Support case-insensitive ZFS subvolumes. + + * grub-core/fs/zfs/zfs.c (mzap_lookup): New parameter case_insensitive. + All users updated. + (zap_hash): Likewise. + (name_cmp): New function. + (zap_leaf_array_equal): New parameter case_insensitive. + All users updated. + (zap_leaf_lookup): Likewise. + (fzap_lookup): Likewise. + (zap_lookup): Likewise. + (dnode_get_path): New parameter case_insensitive. Retrieve case + sensitiviness of a volume. All users updated. + (dnode_get_fullpath): New parameter case_insensitive. + All users updated. + (grub_zfs_dir): Set info.case_insensitiveness. + 2011-11-04 Vladimir Serbinenko Support second redundancy strip on raidz(2,3). diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4c92425dd..9c06574e9 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1448,7 +1448,8 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, */ static grub_err_t mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, - int objsize, char *name, grub_uint64_t * value) + int objsize, char *name, grub_uint64_t * value, + int case_insensitive) { int i, chunks; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; @@ -1456,7 +1457,8 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, chunks = objsize / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { - if (grub_strcmp (mzap_ent[i].mze_name, name) == 0) + if (case_insensitive ? (grub_strcasecmp (mzap_ent[i].mze_name, name) == 0) + : (grub_strcmp (mzap_ent[i].mze_name, name) == 0)) { *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian); return GRUB_ERR_NONE; @@ -1489,7 +1491,8 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, } static grub_uint64_t -zap_hash (grub_uint64_t salt, const char *name) +zap_hash (grub_uint64_t salt, const char *name, + int case_insensitive) { static grub_uint64_t table[256]; const grub_uint8_t *cp; @@ -1507,8 +1510,12 @@ zap_hash (grub_uint64_t salt, const char *name) } } - for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) - crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; + if (case_insensitive) + for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) + crc = (crc >> 8) ^ table[(crc ^ grub_toupper (c)) & 0xFF]; + else + for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) + crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; /* * Only use 28 bits, since we need 4 bits in the cookie for the @@ -1526,10 +1533,34 @@ zap_hash (grub_uint64_t salt, const char *name) * array_len is actual len in bytes (not encoded le_value_length). * buf is null-terminated. */ + +static inline int +name_cmp (const char *s1, const char *s2, grub_size_t n, + int case_insensitive) +{ + const char *t1 = (const char *) s1; + const char *t2 = (const char *) s2; + + if (!case_insensitive) + return grub_memcmp (t1, t2, n); + + while (n--) + { + if (grub_toupper (*t1) != grub_toupper (*t2)) + return (int) grub_toupper (*t1) - (int) grub_toupper (*t2); + + t1++; + t2++; + } + + return 0; +} + /* XXX */ static int zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, - int blksft, int chunk, int array_len, const char *buf) + int blksft, int chunk, int array_len, const char *buf, + int case_insensitive) { int bseen = 0; @@ -1541,7 +1572,8 @@ zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) return (0); - if (grub_memcmp (la->la_array, buf + bseen, toread) != 0) + if (name_cmp ((char *) la->la_array, buf + bseen, toread, + case_insensitive) != 0) break; chunk = grub_zfs_to_cpu16 (la->la_next, endian); bseen += toread; @@ -1582,7 +1614,8 @@ zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, static grub_err_t zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, grub_uint64_t h, - const char *name, grub_uint64_t * value) + const char *name, grub_uint64_t * value, + int case_insensitive) { grub_uint16_t chunk; struct zap_leaf_entry *le; @@ -1614,7 +1647,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, if (zap_leaf_array_equal (l, endian, blksft, grub_zfs_to_cpu16 (le->le_name_chunk,endian), grub_zfs_to_cpu16 (le->le_name_length, endian), - name)) + name, case_insensitive)) { struct zap_leaf_array *la; @@ -1658,7 +1691,8 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) /* XXX */ static grub_err_t fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, - char *name, grub_uint64_t * value, struct grub_zfs_data *data) + char *name, grub_uint64_t * value, struct grub_zfs_data *data, + int case_insensitive) { void *l; grub_uint64_t hash, idx, blkid; @@ -1671,7 +1705,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, if (err) return err; - hash = zap_hash (zap->zap_salt, name); + hash = zap_hash (zap->zap_salt, name, case_insensitive); /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) @@ -1687,7 +1721,8 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, if (err) return err; - err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value); + err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value, + case_insensitive); grub_free (l); return err; } @@ -1806,7 +1841,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, */ static grub_err_t zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int case_insensitive) { grub_uint64_t block_type; int size; @@ -1829,7 +1864,8 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, if (block_type == ZBT_MICRO) { grub_dprintf ("zfs", "micro zap\n"); - err = (mzap_lookup (zapbuf, endian, size, name, val)); + err = mzap_lookup (zapbuf, endian, size, name, val, + case_insensitive); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; @@ -1838,7 +1874,8 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - err = (fzap_lookup (zap_dnode, zapbuf, name, val, data)); + err = fzap_lookup (zap_dnode, zapbuf, name, val, data, + case_insensitive); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; @@ -1964,9 +2001,9 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, */ static grub_err_t dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int *case_insensitive) { - grub_uint64_t objnum, version; + grub_uint64_t objnum, version, insensitivity; char *cname, ch; grub_err_t err = GRUB_ERR_NONE; char *path, *path_buf; @@ -1991,19 +2028,31 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return err; } - err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, data); + err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, + data, 0); if (err) { grub_free (dn_new); return err; } + if (version > ZPL_VERSION) { grub_free (dn_new); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); } - - err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data); + + err = zap_lookup (&(dnode_path->dn), "casesensitivity", &insensitivity, + data, 0); + if (err == GRUB_ERR_FILE_NOT_FOUND) + { + grub_errno = GRUB_ERR_NONE; + insensitivity = 0; + } + if (case_insensitive) + *case_insensitive = insensitivity; + + err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0); if (err) { grub_free (dn_new); @@ -2064,7 +2113,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (path_buf); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, data); + err = zap_lookup (&(dnode_path->dn), cname, &objnum, data, insensitivity); if (err) break; @@ -2296,7 +2345,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, grub_dprintf ("zfs", "alive\n"); - err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data); + err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data, 0); if (err) return err; @@ -2331,7 +2380,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, if (err) return err; - err = zap_lookup (mdn, cname, &objnum, data); + err = zap_lookup (mdn, cname, &objnum, data, 0); if (err) return err; @@ -2374,7 +2423,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) static grub_err_t dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int *case_insensitive) { char *fsname, *snapname; const char *ptr_at, *filename; @@ -2452,7 +2501,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, err = dnode_get (&(data->mos), snapobj, DMU_OT_DSL_DS_SNAP_MAP, mdn, data); if (!err) - err = zap_lookup (mdn, snapname, &headobj, data); + err = zap_lookup (mdn, snapname, &headobj, data, 0); if (!err) err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); if (err) @@ -2476,7 +2525,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_free (snapname); return GRUB_ERR_NONE; } - err = dnode_get_path (mdn, filename, dn, data); + err = dnode_get_path (mdn, filename, dn, data, case_insensitive); grub_free (fsname); grub_free (snapname); return err; @@ -2916,7 +2965,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, - &(data->dnode), &isfs, data); + &(data->dnode), &isfs, data, NULL); if (err) { zfs_unmount (data); @@ -3080,7 +3129,7 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, - &(data->dnode), &isfs, data); + &(data->dnode), &isfs, data, NULL); zfs_unmount (data); return err; } @@ -3118,7 +3167,7 @@ fill_fs_info (struct grub_dirhook_info *info, return; } - err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data); + err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data, 0); if (err) { grub_dprintf ("zfs", "failed here\n"); @@ -3175,6 +3224,7 @@ grub_zfs_dir (grub_device_t device, const char *path, struct grub_zfs_data *data; grub_err_t err; int isfs; + int case_insensitive = 0; auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val); @@ -3219,6 +3269,7 @@ grub_zfs_dir (grub_device_t device, const char *path, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info.mtimeset = 1; info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + info.case_insensitive = case_insensitive; } if (dn.dn.dn_bonustype == DMU_OT_ZNODE) @@ -3273,7 +3324,8 @@ grub_zfs_dir (grub_device_t device, const char *path, data = zfs_mount (device); if (! data) return grub_errno; - err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data); + err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data, + &case_insensitive); if (err) { zfs_unmount (data); From c2fd16cacb3edf41efe3b0ffa266c54c8af9af6f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 15:19:23 +0100 Subject: [PATCH 154/315] Support third redundancy strip on raidz3. * grub-core/fs/zfs/zfs.c (recovery): Add Gauss for general case. Return error on singularity. All users updated. (read_device): Don't stop on 3rd failure on raidz3. --- ChangeLog | 8 +++ grub-core/fs/zfs/zfs.c | 140 +++++++++++++++++++++++++++++++++-------- 2 files changed, 123 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48c43467b..70dc4e4f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-04 Vladimir Serbinenko + + Support third redundancy strip on raidz3. + + * grub-core/fs/zfs/zfs.c (recovery): Add Gauss for general case. + Return error on singularity. All users updated. + (read_device): Don't stop on 3rd failure on raidz3. + 2011-11-04 Vladimir Serbinenko Support case-insensitive ZFS subvolumes. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9c06574e9..f892290a1 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -893,14 +893,15 @@ gf_mul (grub_uint8_t a, grub_uint8_t b) return powx[powx_inv[a] + powx_inv[b]]; } -static inline void +static inline grub_err_t recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, const unsigned *powers, const int *idx) { + grub_dprintf ("zfs", "recovering %u bufers\n", nbufs); /* Now we have */ /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ - /* Since nbufs <= 3 let's be lazy. */ + /* Let's invert the matrix in question. */ switch (nbufs) { /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])). */ @@ -909,39 +910,126 @@ recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, int add; grub_uint8_t *a; if (powers[0] == 0 || idx[0] == 0) - return; + return GRUB_ERR_NONE; add = 255 - ((powers[0] * idx[0]) % 255); for (a = bufs[0]; s--; a++) if (*a) *a = powx[powx_inv[*a] + add]; - return; + return GRUB_ERR_NONE; } - /* b_0 = r_0 * (x ** (powers[0] * idx[0])) + r_1 * (x ** (powers[0] * idx[1])) - b_1 = r_0 * (x ** (powers[1] * idx[0])) + r_1 * (x ** (powers[1] * idx[1])) - */ + /* Case 2x2: Let's use the determinant formula. */ case 2: { grub_uint8_t det, det_inv; - grub_uint8_t det0, det1; + grub_uint8_t matrixinv[2][2]; unsigned i; /* The determinant is: */ det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255] ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]); + if (det == 0) + return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); det_inv = powx[255 - powx_inv[det]]; + matrixinv[0][0] = gf_mul (powx[(powers[1] * idx[1]) % 255], det_inv); + matrixinv[1][1] = gf_mul (powx[(powers[0] * idx[0]) % 255], det_inv); + matrixinv[0][1] = gf_mul (powx[(powers[0] * idx[1]) % 255], det_inv); + matrixinv[1][0] = gf_mul (powx[(powers[1] * idx[0]) % 255], det_inv); for (i = 0; i < s; i++) { - det0 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[1]) % 255]) - ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[1]) % 255])); - det1 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[0]) % 255]) - ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[0]) % 255])); + grub_uint8_t b0, b1; + b0 = bufs[0][i]; + b1 = bufs[1][i]; - bufs[0][i] = gf_mul (det0, det_inv); - bufs[1][i] = gf_mul (det1, det_inv); + bufs[0][i] = (gf_mul (b0, matrixinv[0][0]) + ^ gf_mul (b1, matrixinv[0][1])); + bufs[1][i] = (gf_mul (b0, matrixinv[1][0]) + ^ gf_mul (b1, matrixinv[1][1])); } - break; + return GRUB_ERR_NONE; } - } - + /* Otherwise use Gauss. */ + default: + { + grub_uint8_t matrix1[nbufs][nbufs], matrix2[nbufs][nbufs]; + int i, j, k; + + for (i = 0; i < nbufs; i++) + for (j = 0; j < nbufs; j++) + matrix1[i][j] = powx[(powers[i] * idx[j]) % 255]; + for (i = 0; i < nbufs; i++) + for (j = 0; j < nbufs; j++) + matrix2[i][j] = 0; + for (i = 0; i < nbufs; i++) + matrix2[i][i] = 1; + + for (i = 0; i < nbufs; i++) + { + grub_uint8_t mul; + for (j = i; j < nbufs; j++) + if (matrix1[i][j]) + break; + if (j == nbufs) + return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); + if (j != i) + { + int xchng; + xchng = j; + for (j = 0; j < nbufs; j++) + { + grub_uint8_t t; + t = matrix1[xchng][j]; + matrix1[xchng][j] = matrix1[i][j]; + matrix1[i][j] = t; + } + for (j = 0; j < nbufs; j++) + { + grub_uint8_t t; + t = matrix2[xchng][j]; + matrix2[xchng][j] = matrix2[i][j]; + matrix2[i][j] = t; + } + } + mul = powx[255 - powx_inv[matrix1[i][i]]]; + for (j = 0; j < nbufs; j++) + matrix1[i][j] = gf_mul (matrix1[i][j], mul); + for (j = 0; j < nbufs; j++) + matrix2[i][j] = gf_mul (matrix2[i][j], mul); + for (j = i + 1; j < nbufs; j++) + { + mul = matrix1[j][i]; + for (k = 0; k < nbufs; k++) + matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); + for (k = 0; k < nbufs; k++) + matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); + } + } + for (i = nbufs - 1; i >= 0; i--) + { + for (j = 0; j < i; j++) + { + grub_uint8_t mul; + mul = matrix1[j][i]; + for (k = 0; k < nbufs; k++) + matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); + for (k = 0; k < nbufs; k++) + matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); + } + } + + for (i = 0; i < (int) s; i++) + { + grub_uint8_t b[nbufs]; + for (j = 0; j < nbufs; j++) + b[j] = bufs[j][i]; + for (j = 0; j < nbufs; j++) + { + bufs[j][i] = 0; + for (k = 0; k < nbufs; k++) + bufs[j][i] ^= gf_mul (matrix2[j][k], b[k]); + } + } + return GRUB_ERR_NONE; + } + } } static grub_err_t @@ -1040,10 +1128,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); - /* No raidz3 recovery yet. */ - if (err - && failed_devices < desc->nparity - && failed_devices < 2) + if (err && failed_devices < desc->nparity) { recovery_buf[failed_devices] = buf; recovery_len[failed_devices] = csize; @@ -1066,6 +1151,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, unsigned cur_redundancy_pow = 0; unsigned n_redundancy = 0; unsigned i, j; + grub_err_t err; /* Compute mul. x**s has a period of 255. */ if (powx[0] == 0) @@ -1088,7 +1174,6 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, n_redundancy < failed_devices; cur_redundancy_pow++) { - grub_err_t err; high = grub_divmod64 ((offset >> desc->ashift) + cur_redundancy_pow + ((desc->nparity == 1) @@ -1151,10 +1236,15 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint8_t *tmp_recovery_buf[4]; for (j = 0; j < i; j++) tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[j] - 1; - recovery (tmp_recovery_buf, 1, i, redundancy_pow, recovery_idx); + err = recovery (tmp_recovery_buf, 1, i, redundancy_pow, + recovery_idx); + if (err) + return err; } - recovery (recovery_buf, recovery_len[failed_devices - 1], - failed_devices, redundancy_pow, recovery_idx); + err = recovery (recovery_buf, recovery_len[failed_devices - 1], + failed_devices, redundancy_pow, recovery_idx); + if (err) + return err; } return GRUB_ERR_NONE; } From 455377d93d6feb32f661d48adeea62fa4dfe4143 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 12:15:07 +0100 Subject: [PATCH 155/315] * util/grub-install.in: Fix condition for config_opt. --- ChangeLog | 4 ++++ util/grub-install.in | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70dc4e4f3..75cac6a4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-05 Vladimir Serbinenko + + * util/grub-install.in: Fix condition for config_opt. + 2011-11-04 Vladimir Serbinenko Support third redundancy strip on raidz3. diff --git a/util/grub-install.in b/util/grub-install.in index fdbe10e76..26a2523f8 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -577,10 +577,9 @@ else for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg" done + config_opt="-c ${grubdir}/load.cfg " fi - config_opt="-c ${grubdir}/load.cfg " - prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1 fi From c7ba4f6984a646e8d9f5647fe94fef756cd59f42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 14:47:25 +0100 Subject: [PATCH 156/315] Support BtrFS embedding. * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. (grub_btrfs_fs) [GRUB_UTIL]: Set embed. * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. * util/grub-setup.c (setup): Use fs embedding if available. Add additional sanity check. --- ChangeLog | 10 ++++++++++ grub-core/fs/btrfs.c | 30 ++++++++++++++++++++++++++++++ include/grub/fs.h | 9 +++++++++ util/grub-setup.c | 32 +++++++++++++++++++++++++------- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75cac6a4e..8c125fa97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-05 Vladimir Serbinenko + + Support BtrFS embedding. + + * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. + (grub_btrfs_fs) [GRUB_UTIL]: Set embed. + * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. + * util/grub-setup.c (setup): Use fs embedding if available. + Add additional sanity check. + 2011-11-05 Vladimir Serbinenko * util/grub-install.in: Fix condition for config_opt. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 16e034661..3dc680034 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1596,6 +1596,35 @@ grub_btrfs_label (grub_device_t device, char **label) return grub_errno; } +#ifdef GRUB_UTIL +static grub_err_t +grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), + unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + unsigned i; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "BtrFS curently supports only PC-BIOS embedding"); + + if (64 * 2 - 1 < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your core.img is unusually large. " + "It won't fit in the embedding area."); + + *nsectors = 64 * 2 - 1; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = i + 1; + + return GRUB_ERR_NONE; +} +#endif + static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .dir = grub_btrfs_dir, @@ -1605,6 +1634,7 @@ static struct grub_fs grub_btrfs_fs = { .uuid = grub_btrfs_uuid, .label = grub_btrfs_label, #ifdef GRUB_UTIL + .embed = grub_btrfs_embed, .reserved_first_sector = 1, #endif }; diff --git a/include/grub/fs.h b/include/grub/fs.h index 2c39332a9..dd274e151 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -25,6 +25,10 @@ #include #include +/* For embedding types. */ +#ifdef GRUB_UTIL +#include +#endif /* Forward declaration is required, because of mutual reference. */ struct grub_file; @@ -74,6 +78,11 @@ struct grub_fs grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); #ifdef GRUB_UTIL + /* Determine sectors available for embedding. */ + grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors); + /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; #endif diff --git a/util/grub-setup.c b/util/grub-setup.c index 99de26f76..d3f6fe8b8 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -408,29 +408,44 @@ setup (const char *dir, free (tmp_img); - if (! dest_partmap) + if (! dest_partmap && ! fs) { grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); goto unable_to_embed; } - if (multiple_partmaps || fs) + if (multiple_partmaps || (dest_partmap && fs)) { grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); goto unable_to_embed; } - if (!dest_partmap->embed) + if (dest_partmap && !dest_partmap->embed) { grub_util_warn ("Partition style '%s' doesn't support embeding", dest_partmap->name); goto unable_to_embed; } + if (fs && !fs->embed) + { + grub_util_warn ("File system '%s' doesn't support embeding", + fs->name); + goto unable_to_embed; + } + nsec = core_sectors; - err = dest_partmap->embed (dest_dev->disk, &nsec, - GRUB_EMBED_PCBIOS, §ors); - if (nsec > 2 * core_sectors) - nsec = 2 * core_sectors; + if (dest_partmap) + err = dest_partmap->embed (dest_dev->disk, &nsec, + GRUB_EMBED_PCBIOS, §ors); + else + err = fs->embed (dest_dev, &nsec, + GRUB_EMBED_PCBIOS, §ors); + if (!err && nsec < core_sectors) + { + err = grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your embedding area is unusually small. " + "core.img won't fit in it."); + } if (err) { @@ -439,6 +454,9 @@ setup (const char *dir, goto unable_to_embed; } + if (nsec > 2 * core_sectors) + nsec = 2 * core_sectors; + /* Clean out the blocklists. */ block = first_block; while (block->len) From b632b404e08a3b04f5264fd688354934bf7bd3e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 14:50:53 +0100 Subject: [PATCH 157/315] Support zle compression on ZFS. * grub-core/fs/zfs/zfs.c (zle_decompress): New function. (decomp_table): Add zle. * include/grub/zfs/zio.h (zio_compress): Add zle. --- ChangeLog | 8 ++++++++ grub-core/fs/zfs/zfs.c | 34 ++++++++++++++++++++++++++++++++++ include/grub/zfs/zio.h | 1 + 3 files changed, 43 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8c125fa97..9e9f315f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-05 Vladimir Serbinenko + + Support zle compression on ZFS. + + * grub-core/fs/zfs/zfs.c (zle_decompress): New function. + (decomp_table): Add zle. + * include/grub/zfs/zio.h (zio_compress): Add zle. + 2011-11-05 Vladimir Serbinenko Support BtrFS embedding. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index f892290a1..9658dea0d 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -199,6 +199,39 @@ zlib_decompress (void *s, void *d, return GRUB_ERR_NONE; } +static grub_err_t +zle_decompress (void *s, void *d, + grub_size_t slen, grub_size_t dlen) +{ + grub_uint8_t *iptr, *optr; + grub_size_t clen; + for (iptr = s, optr = d; iptr < (grub_uint8_t *) s + slen + && optr < (grub_uint8_t *) d + dlen;) + { + if (*iptr & 0x80) + clen = ((*iptr) & 0x7f) + 0x41; + else + clen = ((*iptr) & 0x3f) + 1; + if ((grub_ssize_t) clen > (grub_uint8_t *) d + dlen - optr) + clen = (grub_uint8_t *) d + dlen - optr; + if (*iptr & 0x40 || *iptr & 0x80) + { + grub_memset (optr, 0, clen); + iptr++; + optr += clen; + continue; + } + if ((grub_ssize_t) clen > (grub_uint8_t *) s + slen - iptr - 1) + clen = (grub_uint8_t *) s + slen - iptr - 1; + grub_memcpy (optr, iptr + 1, clen); + optr += clen; + iptr += clen + 1; + } + if (optr < (grub_uint8_t *) d + dlen) + grub_memset (optr, 0, (grub_uint8_t *) d + dlen - optr); + return GRUB_ERR_NONE; +} + static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ @@ -214,6 +247,7 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ + {"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 3dafb4028..29451593f 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -86,6 +86,7 @@ enum zio_compress { ZIO_COMPRESS_GZIP7, ZIO_COMPRESS_GZIP8, ZIO_COMPRESS_GZIP9, + ZIO_COMPRESS_ZLE, ZIO_COMPRESS_FUNCTIONS }; From 1bc7cc1b4d850e2ed4d0562798a41f411623c1e1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 13:18:27 +0100 Subject: [PATCH 158/315] First part of zfs-crypto. CCM support with 0-filled keys --- grub-core/fs/zfs/zfs.c | 422 ++++++++++++++++++++++++++++++------- grub-core/lib/crypto.c | 5 +- include/grub/crypto.h | 4 +- include/grub/zfs/dmu.h | 1 + include/grub/zfs/dsl_dir.h | 4 +- include/grub/zfs/zio.h | 1 + 6 files changed, 360 insertions(+), 77 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9658dea0d..9da4d70e2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -52,6 +52,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -124,6 +125,23 @@ static grub_dl_t my_mod; #define NBBY 8 #endif +enum grub_zfs_algo + { + GRUB_ZFS_ALGO_CCM, + GRUB_ZFS_ALGO_GCM, + }; + +struct grub_zfs_key +{ + grub_uint64_t algo; + grub_uint8_t enc_nonce[13]; + grub_uint8_t unused[3]; + grub_uint8_t enc_key[48]; + grub_uint8_t unknown_purpose_nonce[13]; + grub_uint8_t unused2[3]; + grub_uint8_t unknown_purpose_key[48]; +}; + extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -161,6 +179,14 @@ struct grub_zfs_device_desc int original; }; +struct subvolume +{ + dnode_end_t mdn; + grub_uint64_t obj; + grub_uint64_t case_insensitive; + grub_crypto_cipher_handle_t cipher; +}; + struct grub_zfs_data { /* cache for a file block of the currently zfs_open()-ed file */ @@ -176,8 +202,8 @@ struct grub_zfs_data grub_zfs_endian_t dnode_endian; dnode_end_t mos; - dnode_end_t mdn; dnode_end_t dnode; + struct subvolume subvol; struct grub_zfs_device_desc *devices_attached; unsigned n_devices_attached; @@ -292,6 +318,7 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { {fletcher_4, 1, 0, "fletcher4"}, {zio_checksum_SHA256, 1, 0, "SHA256"}, {NULL, 0, 0, "zilog2"}, + {zio_checksum_SHA256, 1, 0, "SHA256+MAC"}, }; /* @@ -302,7 +329,8 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, char *buf, grub_size_t size) + grub_zfs_endian_t endian, + char *buf, grub_size_t size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; @@ -312,7 +340,7 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, { grub_dprintf ("zfs", "unknown checksum function %d\n", checksum); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unknown checksum function %d", checksum); + "unknown checksum function %d", checksum); } if (ci->ci_eck) @@ -326,10 +354,8 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, else ci->ci_func (buf, size, endian, &actual_cksum); - if ((actual_cksum.zc_word[0] != zc.zc_word[0]) - || (actual_cksum.zc_word[1] != zc.zc_word[1]) - || (actual_cksum.zc_word[2] != zc.zc_word[2]) - || (actual_cksum.zc_word[3] != zc.zc_word[3])) + if (grub_memcmp (&actual_cksum, &zc, + checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20) != 0) { grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name); grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n", @@ -1410,16 +1436,67 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, return err; } +static grub_err_t +grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint32_t mac[4]; + unsigned i, j; + grub_err_t err; + + grub_memcpy (iv + 1, nonce, 15 - l); + + iv[0] = (l - 1) | (((m-2) / 2) << 3); + for (j = 0; j < l; j++) + iv[15 - j] = psize >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); + if (err) + return err; + + iv[0] = l - 1; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < l; j++) + iv[15 - j] = (i + 1) >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + grub_crypto_xor (mac, mac, out + 16 * i, csize); + err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); + if (err) + return err; + } + for (j = 0; j < l; j++) + iv[15 - j] = 0; + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + if (mac_out) + grub_crypto_xor (mac_out, mac, mul, m); + return GRUB_ERR_NONE; +} + /* * Read in a block of data, verify its checksum, decompress if needed, * and put the uncompressed data in buf. */ static grub_err_t -zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, +zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, grub_size_t *size, struct grub_zfs_data *data) { grub_size_t lsize, psize; - unsigned int comp; + unsigned int comp, encrypted; char *compbuf = NULL; grub_err_t err; zio_cksum_t zc = bp->blk_cksum; @@ -1429,6 +1506,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; + encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3); lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); @@ -1447,7 +1525,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, if (comp != ZIO_COMPRESS_OFF) { - compbuf = grub_malloc (psize); + compbuf = grub_malloc (ALIGN_UP (psize, 16)); if (! compbuf) return grub_errno; } @@ -1462,8 +1540,10 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, *buf = NULL; return err; } + grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize); - err = zio_checksum_verify (zc, checksum, endian, compbuf, psize); + err = zio_checksum_verify (zc, checksum, endian, + compbuf, psize); if (err) { grub_dprintf ("zfs", "incorrect checksum\n"); @@ -1472,6 +1552,45 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, return err; } + if (encrypted) + { + grub_uint32_t mac[4]; + unsigned i; + grub_uint32_t sw[4]; + + grub_memcpy (sw, &(bp)->blk_dva[encrypted], 16); + for (i = 0; i < 4; i++) + sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + + if (!data->subvol.cipher) + { + grub_free (compbuf); + *buf = NULL; + return grub_error (GRUB_ERR_ACCESS_DENIED, + "no decryption key available");; + } + err = grub_ccm_decrypt (data->subvol.cipher, + (grub_uint8_t *) compbuf, + (grub_uint8_t *) compbuf, + psize, mac, + sw + 1, 3, 12); + if (err) + { + grub_free (compbuf); + *buf = NULL; + return err; + } + + for (i = 0; i < 3; i++) + if (grub_zfs_to_cpu32 (((grub_uint32_t *) &zc + 5)[i], endian) + != grub_be_to_cpu32 (mac[i])) + { + grub_free (compbuf); + *buf = NULL; + return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); + } + } + if (comp != ZIO_COMPRESS_OFF) { *buf = grub_malloc (lsize); @@ -1572,7 +1691,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, */ static grub_err_t mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, - int objsize, char *name, grub_uint64_t * value, + int objsize, const char *name, grub_uint64_t * value, int case_insensitive) { int i, chunks; @@ -1799,8 +1918,8 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); - if (zap->zap_flags != 0) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags"); + /* if (zap->zap_flags != 0) + return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags");*/ if (zap->zap_salt == 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); @@ -1854,9 +1973,11 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* XXX */ static int fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, - int NESTED_FUNC_ATTR (*hook) (const char *name, - grub_uint64_t val), - struct grub_zfs_data *data) + int NESTED_FUNC_ATTR (*hook) (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize), + struct grub_zfs_data *data) { zap_leaf_phys_t *l; void *l_in; @@ -1918,9 +2039,9 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++) { char *buf; - struct zap_leaf_array *la; struct zap_leaf_entry *le; - grub_uint64_t val; + char *val; + grub_size_t val_length; le = ZAP_LEAF_ENTRY (l, blksft, chunk); /* Verify the chunk entry */ @@ -1940,24 +2061,28 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, } buf[le->le_name_length] = 0; - if (le->le_int_size != 8 - || grub_zfs_to_cpu16 (le->le_value_length, endian) != 1) - continue; + val_length = ((int) le->le_value_length + * (int) le->le_int_size); + val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian)); + if (zap_leaf_array_get (l, endian, blksft, + grub_zfs_to_cpu16 (le->le_value_chunk, + endian), + val_length, val)) + { + grub_free (buf); + grub_free (val); + continue; + } - /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, - grub_zfs_to_cpu16 (le->le_value_chunk, - endian)).l_array; - val = grub_be_to_cpu64 (la->la_array64); - if (hook (buf, val)) + if (hook (buf, val, le->le_value_length, le->le_int_size)) return 1; grub_free (buf); + grub_free (val); } } return 0; } - /* * Read in the data of a zap object and find the value for a matching * property name. @@ -2008,9 +2133,68 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); } +static int +zap_iterate_u64 (dnode_end_t * zap_dnode, + int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_uint64_t val), + struct grub_zfs_data *data) +{ + grub_uint64_t block_type; + int size; + void *zapbuf; + grub_err_t err; + int ret; + grub_zfs_endian_t endian; + + auto int NESTED_FUNC_ATTR transform (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + + int NESTED_FUNC_ATTR transform (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + if (elemsize != sizeof (grub_uint64_t) || nelem != 1) + return 0; + return hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in)); + } + + /* Read in the first block of the zap object data. */ + size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; + err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); + if (err) + return 0; + block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); + + grub_dprintf ("zfs", "zap iterate\n"); + + if (block_type == ZBT_MICRO) + { + grub_dprintf ("zfs", "micro zap\n"); + ret = mzap_iterate (zapbuf, endian, size, hook); + grub_free (zapbuf); + return ret; + } + else if (block_type == ZBT_HEADER) + { + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ + ret = fzap_iterate (zap_dnode, zapbuf, transform, data); + grub_free (zapbuf); + return ret; + } + grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + return 0; +} + static int zap_iterate (dnode_end_t * zap_dnode, - int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val), + int NESTED_FUNC_ATTR (*hook) (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize), struct grub_zfs_data *data) { grub_uint64_t block_type; @@ -2031,12 +2215,10 @@ zap_iterate (dnode_end_t * zap_dnode, if (block_type == ZBT_MICRO) { - grub_dprintf ("zfs", "micro zap\n"); - ret = mzap_iterate (zapbuf, endian, size, hook); - grub_free (zapbuf); - return ret; + grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected"); + return 0; } - else if (block_type == ZBT_HEADER) + if (block_type == ZBT_HEADER) { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ @@ -2124,10 +2306,10 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, * */ static grub_err_t -dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, - struct grub_zfs_data *data, int *case_insensitive) +dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + struct grub_zfs_data *data) { - grub_uint64_t objnum, version, insensitivity; + grub_uint64_t objnum, version; char *cname, ch; grub_err_t err = GRUB_ERR_NONE; char *path, *path_buf; @@ -2144,7 +2326,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, dn_new->next = 0; dnode_path = root = dn_new; - err = dnode_get (mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, &(dnode_path->dn), data); if (err) { @@ -2166,15 +2348,14 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); } - err = zap_lookup (&(dnode_path->dn), "casesensitivity", &insensitivity, + err = zap_lookup (&(dnode_path->dn), "casesensitivity", + &subvol->case_insensitive, data, 0); if (err == GRUB_ERR_FILE_NOT_FOUND) { grub_errno = GRUB_ERR_NONE; - insensitivity = 0; + subvol->case_insensitive = 0; } - if (case_insensitive) - *case_insensitive = insensitivity; err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0); if (err) @@ -2183,7 +2364,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return err; } - err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); if (err) { grub_free (dn_new); @@ -2237,7 +2418,8 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (path_buf); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, data, insensitivity); + err = zap_lookup (&(dnode_path->dn), cname, &objnum, + data, subvol->case_insensitive); if (err) break; @@ -2251,7 +2433,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, dnode_path = dn_new; objnum = ZFS_DIRENT_OBJ (objnum); - err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); if (err) break; @@ -2545,15 +2727,93 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) } static grub_err_t -dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, - grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, - struct grub_zfs_data *data, int *case_insensitive) +dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + dnode_end_t * dn, int *isfs, + struct grub_zfs_data *data) { char *fsname, *snapname; const char *ptr_at, *filename; grub_uint64_t headobj; + grub_uint64_t keychainobj; grub_err_t err; + auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR iterate_zap_key (const char *name __attribute__ ((unused)), + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + const struct grub_zfs_key *key = val_in; + grub_crypto_cipher_handle_t cipher; + grub_uint8_t wrapping_key[32], decrypted[32], mac[32]; + unsigned keylen; + + if (elemsize != 1 || nelem != sizeof (*key)) + { + grub_dprintf ("zfs", "Unexpected key length %" PRIuGRUB_SIZE + " x %" PRIuGRUB_SIZE "\n", nelem, elemsize); + return 0; + } + + if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) + == 0) + keylen = 16; + else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) + keylen = 24; + else + keylen = 32; + + grub_memset (wrapping_key, 0, sizeof (wrapping_key)); + + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, wrapping_key, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + return 0; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + return 0; + } + subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!subvol->cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + return 0; + } + ptr_at = grub_strchr (fullpath, '@'); if (! ptr_at) { @@ -2605,29 +2865,47 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian); - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); - err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &subvol->mdn, + data); if (err) { grub_free (fsname); grub_free (snapname); return err; } - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); + + keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); + if (keychainobj) + { + dnode_end_t keychain_dn; + err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, + &keychain_dn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + zap_iterate (&keychain_dn, iterate_zap_key, data); + } + if (snapname) { grub_uint64_t snapobj; - snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_snapnames_zapobj, mdn->endian); + snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&subvol->mdn.dn))->ds_snapnames_zapobj, subvol->mdn.endian); err = dnode_get (&(data->mos), snapobj, - DMU_OT_DSL_DS_SNAP_MAP, mdn, data); + DMU_OT_DSL_DS_SNAP_MAP, &subvol->mdn, data); if (!err) - err = zap_lookup (mdn, snapname, &headobj, data, 0); + err = zap_lookup (&subvol->mdn, snapname, &headobj, data, 0); if (!err) - err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, + &subvol->mdn, data); if (err) { grub_free (fsname); @@ -2636,12 +2914,11 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, } } - if (mdnobj) - *mdnobj = headobj; + subvol->obj = headobj; - make_mdn (mdn, data); + make_mdn (&subvol->mdn, data); - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); if (*isfs) { @@ -2649,7 +2926,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_free (snapname); return GRUB_ERR_NONE; } - err = dnode_get_path (mdn, filename, dn, data, case_insensitive); + err = dnode_get_path (subvol, filename, dn, data); grub_free (fsname); grub_free (snapname); return err; @@ -3088,8 +3365,8 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) if (! data) return grub_errno; - err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, - &(data->dnode), &isfs, data, NULL); + err = dnode_get_fullpath (fsfilename, &(data->subvol), + &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); @@ -3252,8 +3529,9 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, if (! data) return grub_errno; - err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, - &(data->dnode), &isfs, data, NULL); + err = dnode_get_fullpath (fsfilename, &(data->subvol), + &(data->dnode), &isfs, data); + *mdnobj = data->subvol.obj; zfs_unmount (data); return err; } @@ -3348,7 +3626,6 @@ grub_zfs_dir (grub_device_t device, const char *path, struct grub_zfs_data *data; grub_err_t err; int isfs; - int case_insensitive = 0; auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val); @@ -3361,7 +3638,7 @@ grub_zfs_dir (grub_device_t device, const char *path, dnode_end_t dn; grub_memset (&info, 0, sizeof (info)); - dnode_get (&(data->mdn), val, 0, &dn, data); + dnode_get (&(data->subvol.mdn), val, 0, &dn, data); if (dn.dn.dn_bonustype == DMU_OT_SA) { @@ -3393,7 +3670,7 @@ grub_zfs_dir (grub_device_t device, const char *path, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info.mtimeset = 1; info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); - info.case_insensitive = case_insensitive; + info.case_insensitive = data->subvol.case_insensitive; } if (dn.dn.dn_bonustype == DMU_OT_ZNODE) @@ -3448,8 +3725,7 @@ grub_zfs_dir (grub_device_t device, const char *path, data = zfs_mount (device); if (! data) return grub_errno; - err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data, - &case_insensitive); + err = dnode_get_fullpath (path, &(data->subvol), &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); @@ -3475,7 +3751,7 @@ grub_zfs_dir (grub_device_t device, const char *path, return err; } - zap_iterate (&dn, iterate_zap_fs, data); + zap_iterate_u64 (&dn, iterate_zap_fs, data); err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); if (err) @@ -3494,7 +3770,7 @@ grub_zfs_dir (grub_device_t device, const char *path, return err; } - zap_iterate (&dn, iterate_zap_snap, data); + zap_iterate_u64 (&dn, iterate_zap_snap, data); } else { @@ -3503,7 +3779,7 @@ grub_zfs_dir (grub_device_t device, const char *path, zfs_unmount (data); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - zap_iterate (&(data->dnode), iterate_zap, data); + zap_iterate_u64 (&(data->dnode), iterate_zap, data); } zfs_unmount (data); return grub_errno; diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 8876cc326..f858be9c6 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -210,9 +210,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) diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 10368d99f..573893a3e 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -203,7 +203,7 @@ 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); gcry_err_code_t grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher, void *out, void *in, grub_size_t size, @@ -251,11 +251,13 @@ extern gcry_md_spec_t _gcry_digest_spec_sha1; extern gcry_md_spec_t _gcry_digest_spec_sha256; extern gcry_md_spec_t _gcry_digest_spec_sha512; extern gcry_md_spec_t _gcry_digest_spec_crc32; +extern gcry_cipher_spec_t _gcry_cipher_spec_aes; #define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5) #define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1) #define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256) #define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512) #define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32) +#define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes) /* 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, diff --git a/include/grub/zfs/dmu.h b/include/grub/zfs/dmu.h index bee317e8a..8fc6dc5b5 100644 --- a/include/grub/zfs/dmu.h +++ b/include/grub/zfs/dmu.h @@ -88,6 +88,7 @@ typedef enum dmu_object_type { DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ + DMU_OT_DSL_KEYCHAIN = 54, DMU_OT_NUMTYPES } dmu_object_type_t; diff --git a/include/grub/zfs/dsl_dir.h b/include/grub/zfs/dsl_dir.h index 41d77c790..6542a77fe 100644 --- a/include/grub/zfs/dsl_dir.h +++ b/include/grub/zfs/dsl_dir.h @@ -42,7 +42,9 @@ typedef struct dsl_dir_phys { grub_uint64_t dd_reserved; grub_uint64_t dd_props_zapobj; grub_uint64_t dd_deleg_zapobj; /* dataset permissions */ - grub_uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */ + grub_uint64_t unused[7]; + grub_uint64_t keychain; + grub_uint64_t unused2[12]; } dsl_dir_phys_t; #endif /* _SYS_DSL_DIR_H */ diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 29451593f..8b645c063 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -65,6 +65,7 @@ enum zio_checksum { ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_ZILOG2, + ZIO_CHECKSUM_SHA256_MAC, ZIO_CHECKSUM_FUNCTIONS }; From 2cdc899567c4db45ab0a3a5eae2aa91faa7cff92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 14:44:29 +0100 Subject: [PATCH 159/315] ZFS crypto key adding --- grub-core/fs/zfs/zfs.c | 114 +++++++++++++++++++++++-------------- grub-core/fs/zfs/zfsinfo.c | 67 ++++++++++++++++++++++ include/grub/zfs/zfs.h | 2 + util/grub-fstest.c | 26 +++++++++ 4 files changed, 165 insertions(+), 44 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9da4d70e2..4008d17f4 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010,2011 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. * * GRUB is free software; you can redistribute it and/or modify @@ -142,6 +142,12 @@ struct grub_zfs_key grub_uint8_t unknown_purpose_key[48]; }; +struct grub_zfs_wrap_key +{ + struct grub_zfs_wrap_key *next; + grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; +}; + extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -216,6 +222,21 @@ struct grub_zfs_data grub_uint64_t guid; }; +static struct grub_zfs_wrap_key *zfs_wrap_keys; + +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in) +{ + struct grub_zfs_wrap_key *key; + key = grub_malloc (sizeof (*key)); + if (!key) + return grub_errno; + grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->next = zfs_wrap_keys; + zfs_wrap_keys = key; + return GRUB_ERR_NONE; +} + static grub_err_t zlib_decompress (void *s, void *d, grub_size_t slen, grub_size_t dlen) @@ -2747,9 +2768,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_size_t elemsize) { const struct grub_zfs_key *key = val_in; - grub_crypto_cipher_handle_t cipher; - grub_uint8_t wrapping_key[32], decrypted[32], mac[32]; unsigned keylen; + struct grub_zfs_wrap_key *wrap_key; if (elemsize != 1 || nelem != sizeof (*key)) { @@ -2766,51 +2786,57 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, else keylen = 32; - grub_memset (wrapping_key, 0, sizeof (wrapping_key)); + for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) + { + grub_crypto_cipher_handle_t cipher; + grub_uint8_t decrypted[32], mac[32]; + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, + (const grub_uint8_t *) wrap_key->key, + keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } - cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (cipher, wrapping_key, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) + != 0)) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!subvol->cipher) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } return 0; } - - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - return 0; - } - subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!subvol->cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - return 0; } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 8c073fab5..dfc238d11 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -389,14 +391,78 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, return GRUB_ERR_NONE; } +static const struct grub_arg_option options[] = + { + {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, + {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, + {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint8_t buf[1024]; + grub_ssize_t real_size; + + if (argc > 0) + { + grub_file_t file; + file = grub_file_open (args[0]); + if (!file) + return grub_errno; + real_size = grub_file_read (file, buf, 1024); + if (real_size < 0) + return grub_errno; + } + if (ctxt->state[0].set + || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + { + grub_err_t err; + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + + if (ctxt->state[1].set) + { + int i; + grub_err_t err; + if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); + for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + { + char c1 = grub_tolower (buf[2 * i]) - '0'; + char c2 = grub_tolower (buf[2 * i + 1]) - '0'; + if (c1 > 9) + c1 += '0' - 'a' + 10; + if (c2 > 9) + c2 += '0' - 'a' + 10; + buf[i] = (c1 << 4) | c2; + } + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; +} static grub_command_t cmd_info, cmd_bootfs; +static grub_extcmd_t cmd_key; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, "zfsinfo DEVICE", "Print ZFS info about DEVICE."); + cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, + "zfskey [-h|-p|-r] [FILE]", + "Import ZFS wrapping key stored in FILE.", + options); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, "zfs-bootfs FILESYSTEM [VARIABLE]", "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); @@ -406,4 +472,5 @@ GRUB_MOD_FINI (zfsinfo) { grub_unregister_command (cmd_info); grub_unregister_command (cmd_bootfs); + grub_unregister_extcmd (cmd_key); } diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index d7029903a..62b72776e 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -121,5 +121,7 @@ char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, grub_size_t index); int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, const char *name); +grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); +#define GRUB_ZFS_MAX_KEYLEN 32 #endif /* ! GRUB_ZFS_HEADER */ diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 996d71c3a..0d0801187 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -438,6 +439,7 @@ static struct argp_option options[] = { {"diskcount", 'c', "N", 0, N_("N input files."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, + {"zfs-key-file", 'K', N_("KEY_FILENAME"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {"uncompress", 'u', NULL, OPTION_ARG_OPTIONAL, N_("Uncompress data."), 2}, {0, 0, 0, 0, 0, 0} @@ -462,6 +464,30 @@ argp_parser (int key, char *arg, struct argp_state *state) root = arg; return 0; + case 'K': + { + FILE *f; + ssize_t real_size; + grub_uint8_t buf[GRUB_ZFS_MAX_KEYLEN]; + f = fopen (arg, "rb"); + if (!f) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + return 0; + } + real_size = fread (buf, 1, GRUB_ZFS_MAX_KEYLEN, f); + if (real_size < 0) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + fclose (f); + return 0; + } + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + grub_zfs_add_key (buf); + } + return 0; + case 'C': mount_crypt = 1; return 0; From f003a8c5e75df1c0b01511195e62f2afe317aa58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 15:18:25 +0100 Subject: [PATCH 160/315] Move ZFS crypto to separate module --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/zfs/zfs.c | 255 ++++++---------------------- grub-core/fs/zfs/zfscrypt.c | 324 ++++++++++++++++++++++++++++++++++++ grub-core/fs/zfs/zfsinfo.c | 67 -------- grub-core/lib/crypto.c | 8 - include/grub/crypto.h | 8 +- include/grub/zfs/spa.h | 24 ++- include/grub/zfs/zfs.h | 21 +++ 9 files changed, 415 insertions(+), 298 deletions(-) create mode 100644 grub-core/fs/zfs/zfscrypt.c diff --git a/Makefile.util.def b/Makefile.util.def index 17894b1d2..15a309367 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -82,6 +82,7 @@ library = { common = grub-core/fs/ufs2.c; common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; + common = grub-core/fs/zfs/zfscrypt.c; common = grub-core/fs/zfs/zfs.c; common = grub-core/fs/zfs/zfsinfo.c; common = grub-core/fs/zfs/zfs_lzjb.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b2e8e7aa2..9590188fb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1116,6 +1116,11 @@ module = { common = fs/zfs/zfs_fletcher.c; }; +module = { + name = zfscrypt; + common = fs/zfs/zfscrypt.c; +}; + module = { name = zfsinfo; common = fs/zfs/zfsinfo.c; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4008d17f4..3558bd8bb 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -125,29 +125,6 @@ static grub_dl_t my_mod; #define NBBY 8 #endif -enum grub_zfs_algo - { - GRUB_ZFS_ALGO_CCM, - GRUB_ZFS_ALGO_GCM, - }; - -struct grub_zfs_key -{ - grub_uint64_t algo; - grub_uint8_t enc_nonce[13]; - grub_uint8_t unused[3]; - grub_uint8_t enc_key[48]; - grub_uint8_t unknown_purpose_nonce[13]; - grub_uint8_t unused2[3]; - grub_uint8_t unknown_purpose_key[48]; -}; - -struct grub_zfs_wrap_key -{ - struct grub_zfs_wrap_key *next; - grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; -}; - extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -222,20 +199,13 @@ struct grub_zfs_data grub_uint64_t guid; }; -static struct grub_zfs_wrap_key *zfs_wrap_keys; - -grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in) -{ - struct grub_zfs_wrap_key *key; - key = grub_malloc (sizeof (*key)); - if (!key) - return grub_errno; - grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); - key->next = zfs_wrap_keys; - zfs_wrap_keys = key; - return GRUB_ERR_NONE; -} +grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian) = NULL; +grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, + grub_size_t keysize) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -409,14 +379,16 @@ static int vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) { grub_zfs_endian_t ub1_endian, ub2_endian; - if (grub_zfs_to_cpu64 (ub1->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) - ub1_endian = LITTLE_ENDIAN; + if (grub_zfs_to_cpu64 (ub1->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC) + ub1_endian = GRUB_ZFS_LITTLE_ENDIAN; else - ub1_endian = BIG_ENDIAN; - if (grub_zfs_to_cpu64 (ub2->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) - ub2_endian = LITTLE_ENDIAN; + ub1_endian = GRUB_ZFS_BIG_ENDIAN; + if (grub_zfs_to_cpu64 (ub2->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC) + ub2_endian = GRUB_ZFS_LITTLE_ENDIAN; else - ub2_endian = BIG_ENDIAN; + ub2_endian = GRUB_ZFS_BIG_ENDIAN; if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) @@ -448,20 +420,23 @@ uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset) { uberblock_t *uber = &ub->ubp_uberblock; grub_err_t err; - grub_zfs_endian_t endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t endian = GRUB_ZFS_UNKNOWN_ENDIAN; zio_cksum_t zc; - if (grub_zfs_to_cpu64 (uber->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC - && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) > 0 - && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) <= SPA_VERSION) - endian = LITTLE_ENDIAN; + if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN) + <= SPA_VERSION) + endian = GRUB_ZFS_LITTLE_ENDIAN; - if (grub_zfs_to_cpu64 (uber->ub_magic, BIG_ENDIAN) == UBERBLOCK_MAGIC - && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) > 0 - && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) <= SPA_VERSION) - endian = BIG_ENDIAN; + if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_BIG_ENDIAN) == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN) + <= SPA_VERSION) + endian = GRUB_ZFS_BIG_ENDIAN; - if (endian == UNKNOWN_ENDIAN) + if (endian == GRUB_ZFS_UNKNOWN_ENDIAN) return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic"); grub_memset (&zc, 0, sizeof (zc)); @@ -1382,7 +1357,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, zio_gb = grub_malloc (SPA_GANGBLOCKSIZE); if (!zio_gb) return grub_errno; - grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" + grub_dprintf ("zfs", endian == GRUB_ZFS_LITTLE_ENDIAN ? "little-endian gang\n" :"big-endian gang\n"); err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE); @@ -1457,57 +1432,6 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, return err; } -static grub_err_t -grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, - grub_uint8_t *out, const grub_uint8_t *in, - grub_size_t psize, - void *mac_out, const void *nonce, - unsigned l, unsigned m) -{ - grub_uint8_t iv[16]; - grub_uint8_t mul[16]; - grub_uint32_t mac[4]; - unsigned i, j; - grub_err_t err; - - grub_memcpy (iv + 1, nonce, 15 - l); - - iv[0] = (l - 1) | (((m-2) / 2) << 3); - for (j = 0; j < l; j++) - iv[15 - j] = psize >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); - if (err) - return err; - - iv[0] = l - 1; - - for (i = 0; i < (psize + 15) / 16; i++) - { - grub_size_t csize; - csize = 16; - if (csize > psize - 16 * i) - csize = psize - 16 * i; - for (j = 0; j < l; j++) - iv[15 - j] = (i + 1) >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); - grub_crypto_xor (mac, mac, out + 16 * i, csize); - err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); - if (err) - return err; - } - for (j = 0; j < l; j++) - iv[15 - j] = 0; - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - if (mac_out) - grub_crypto_xor (mac_out, mac, mul, m); - return GRUB_ERR_NONE; -} - /* * Read in a block of data, verify its checksum, decompress if needed, * and put the uncompressed data in buf. @@ -1575,41 +1499,18 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (encrypted) { - grub_uint32_t mac[4]; - unsigned i; - grub_uint32_t sw[4]; - - grub_memcpy (sw, &(bp)->blk_dva[encrypted], 16); - for (i = 0; i < 4; i++) - sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); - - if (!data->subvol.cipher) - { - grub_free (compbuf); - *buf = NULL; - return grub_error (GRUB_ERR_ACCESS_DENIED, - "no decryption key available");; - } - err = grub_ccm_decrypt (data->subvol.cipher, - (grub_uint8_t *) compbuf, - (grub_uint8_t *) compbuf, - psize, mac, - sw + 1, 3, 12); + if (!grub_zfs_decrypt) + err = grub_error (GRUB_ERR_BAD_FS, "zfscrypto module not loaded"); + else + err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], + compbuf, psize, ((grub_uint32_t *) &zc + 5), + endian); if (err) { grub_free (compbuf); *buf = NULL; return err; } - - for (i = 0; i < 3; i++) - if (grub_zfs_to_cpu32 (((grub_uint32_t *) &zc + 5)[i], endian) - != grub_be_to_cpu32 (mac[i])) - { - grub_free (compbuf); - *buf = NULL; - return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); - } } if (comp != ZIO_COMPRESS_OFF) @@ -2767,76 +2668,14 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_size_t nelem, grub_size_t elemsize) { - const struct grub_zfs_key *key = val_in; - unsigned keylen; - struct grub_zfs_wrap_key *wrap_key; - - if (elemsize != 1 || nelem != sizeof (*key)) + if (elemsize != 1) { - grub_dprintf ("zfs", "Unexpected key length %" PRIuGRUB_SIZE - " x %" PRIuGRUB_SIZE "\n", nelem, elemsize); + grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", + elemsize); return 0; } - if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) - == 0) - keylen = 16; - else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) - keylen = 24; - else - keylen = 32; - - for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) - { - grub_crypto_cipher_handle_t cipher; - grub_uint8_t decrypted[32], mac[32]; - cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (cipher, - (const grub_uint8_t *) wrap_key->key, - keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); - if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) - != 0)) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!subvol->cipher) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - return 0; - } + subvol->cipher = grub_zfs_load_key (val_in, nelem); return 0; } @@ -2904,7 +2743,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); - if (keychainobj) + if (grub_zfs_load_key && keychainobj) { dnode_end_t keychain_dn; err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, @@ -2918,7 +2757,6 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, zap_iterate (&keychain_dn, iterate_zap_key, data); } - if (snapname) { grub_uint64_t snapobj; @@ -3221,6 +3059,7 @@ zfs_unmount (struct grub_zfs_data *data) grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); + grub_crypto_cipher_close (data->subvol.cipher); grub_free (data); } @@ -3236,7 +3075,7 @@ zfs_mount (grub_device_t dev) grub_err_t err; objset_phys_t *osp = 0; grub_size_t ospsize; - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; if (! dev->disk) @@ -3267,8 +3106,8 @@ zfs_mount (grub_device_t dev) ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); + GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); err = zio_read (&ub->ub_rootbp, ub_endian, (void **) &osp, &ospsize, data); @@ -3357,7 +3196,7 @@ static grub_err_t zfs_mtime (grub_device_t device, grub_int32_t *mt) { struct grub_zfs_data *data; - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; *mt = 0; @@ -3368,8 +3207,8 @@ zfs_mtime (grub_device_t device, grub_int32_t *mt) ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); + GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian); zfs_unmount (data); diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c new file mode 100644 index 000000000..251538041 --- /dev/null +++ b/grub-core/fs/zfs/zfscrypt.c @@ -0,0 +1,324 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +enum grub_zfs_algo + { + GRUB_ZFS_ALGO_CCM, + GRUB_ZFS_ALGO_GCM, + }; + +struct grub_zfs_key +{ + grub_uint64_t algo; + grub_uint8_t enc_nonce[13]; + grub_uint8_t unused[3]; + grub_uint8_t enc_key[48]; + grub_uint8_t unknown_purpose_nonce[13]; + grub_uint8_t unused2[3]; + grub_uint8_t unknown_purpose_key[48]; +}; + +struct grub_zfs_wrap_key +{ + struct grub_zfs_wrap_key *next; + grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; +}; + +static struct grub_zfs_wrap_key *zfs_wrap_keys; + +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in) +{ + struct grub_zfs_wrap_key *key; + key = grub_malloc (sizeof (*key)); + if (!key) + return grub_errno; + grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->next = zfs_wrap_keys; + zfs_wrap_keys = key; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint32_t mac[4]; + unsigned i, j; + grub_err_t err; + + grub_memcpy (iv + 1, nonce, 15 - l); + + iv[0] = (l - 1) | (((m-2) / 2) << 3); + for (j = 0; j < l; j++) + iv[15 - j] = psize >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); + if (err) + return err; + + iv[0] = l - 1; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < l; j++) + iv[15 - j] = (i + 1) >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + grub_crypto_xor (mac, mac, out + 16 * i, csize); + err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); + if (err) + return err; + } + for (j = 0; j < l; j++) + iv[15 - j] = 0; + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + if (mac_out) + grub_crypto_xor (mac_out, mac, mul, m); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian) +{ + grub_uint32_t mac[4]; + unsigned i; + grub_uint32_t sw[4]; + grub_err_t err; + + grub_memcpy (sw, nonce, 16); + for (i = 0; i < 4; i++) + sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + + if (!cipher) + return grub_error (GRUB_ERR_ACCESS_DENIED, + "no decryption key available");; + err = grub_ccm_decrypt (cipher, + (grub_uint8_t *) buf, + (grub_uint8_t *) buf, + size, mac, + sw + 1, 3, 12); + if (err) + return err; + + for (i = 0; i < 3; i++) + if (grub_zfs_to_cpu32 (expected_mac[i], endian) + != grub_be_to_cpu32 (mac[i])) + return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); + return GRUB_ERR_NONE; +} + +static grub_crypto_cipher_handle_t +grub_zfs_load_key_real (const struct grub_zfs_key *key, + grub_size_t keysize) +{ + unsigned keylen; + struct grub_zfs_wrap_key *wrap_key; + grub_crypto_cipher_handle_t ret = NULL; + grub_err_t err; + + if (keysize != sizeof (*key)) + { + grub_dprintf ("zfs", "Unexpected key size %" PRIuGRUB_SIZE "\n", keysize); + return 0; + } + + if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) + == 0) + keylen = 16; + else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) + keylen = 24; + else + keylen = 32; + + for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) + { + grub_crypto_cipher_handle_t cipher; + grub_uint8_t decrypted[32], mac[32]; + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, + (const grub_uint8_t *) wrap_key->key, + keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) + != 0)) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + ret = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!ret) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + err = grub_crypto_cipher_set_key (ret, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + grub_crypto_cipher_close (ret); + continue; + } + return ret; + } + return NULL; +} + +static const struct grub_arg_option options[] = + { + {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, + {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, + {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint8_t buf[1024]; + grub_ssize_t real_size; + + if (argc > 0) + { + grub_file_t file; + file = grub_file_open (args[0]); + if (!file) + return grub_errno; + real_size = grub_file_read (file, buf, 1024); + if (real_size < 0) + return grub_errno; + } + if (ctxt->state[0].set + || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + { + grub_err_t err; + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + + if (ctxt->state[1].set) + { + int i; + grub_err_t err; + if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); + for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + { + char c1 = grub_tolower (buf[2 * i]) - '0'; + char c2 = grub_tolower (buf[2 * i + 1]) - '0'; + if (c1 > 9) + c1 += '0' - 'a' + 10; + if (c2 > 9) + c2 += '0' - 'a' + 10; + buf[i] = (c1 << 4) | c2; + } + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd_key; + +GRUB_MOD_INIT(zfscrypto) +{ + grub_zfs_decrypt = grub_zfs_decrypt_real; + grub_zfs_load_key = grub_zfs_load_key_real; + cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, + "zfskey [-h|-p|-r] [FILE]", + "Import ZFS wrapping key stored in FILE.", + options); +} + +GRUB_MOD_FINI(zfscrypto) +{ + grub_zfs_decrypt = 0; + grub_zfs_load_key = 0; + grub_unregister_extcmd (cmd_key); +} diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index dfc238d11..3ed2448b0 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -391,78 +390,13 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, return GRUB_ERR_NONE; } -static const struct grub_arg_option options[] = - { - {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, - {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, - {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint8_t buf[1024]; - grub_ssize_t real_size; - - if (argc > 0) - { - grub_file_t file; - file = grub_file_open (args[0]); - if (!file) - return grub_errno; - real_size = grub_file_read (file, buf, 1024); - if (real_size < 0) - return grub_errno; - } - if (ctxt->state[0].set - || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) - { - grub_err_t err; - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; - } - - if (ctxt->state[1].set) - { - int i; - grub_err_t err; - if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); - for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) - { - char c1 = grub_tolower (buf[2 * i]) - '0'; - char c2 = grub_tolower (buf[2 * i + 1]) - '0'; - if (c1 > 9) - c1 += '0' - 'a' + 10; - if (c2 > 9) - c2 += '0' - 'a' + 10; - buf[i] = (c1 << 4) | c2; - } - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; - } - return GRUB_ERR_NONE; -} - static grub_command_t cmd_info, cmd_bootfs; -static grub_extcmd_t cmd_key; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, "zfsinfo DEVICE", "Print ZFS info about DEVICE."); - cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, - "zfskey [-h|-p|-r] [FILE]", - "Import ZFS wrapping key stored in FILE.", - options); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, "zfs-bootfs FILESYSTEM [VARIABLE]", "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); @@ -472,5 +406,4 @@ GRUB_MOD_FINI (zfsinfo) { grub_unregister_command (cmd_info); grub_unregister_command (cmd_bootfs); - grub_unregister_extcmd (cmd_key); } diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index f858be9c6..4dec5c694 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -169,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) { diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 573893a3e..b8a5b3a22 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -26,6 +26,7 @@ #include #include #include +#include typedef enum { @@ -191,8 +192,11 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, const unsigned char *key, unsigned keylen); -void -grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher); +static inline 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); diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h index 22ee03b15..0e29fa44a 100644 --- a/include/grub/zfs/spa.h +++ b/include/grub/zfs/spa.h @@ -20,26 +20,24 @@ #ifndef GRUB_ZFS_SPA_HEADER #define GRUB_ZFS_SPA_HEADER 1 -typedef enum grub_zfs_endian - { - UNKNOWN_ENDIAN = -2, - LITTLE_ENDIAN = -1, - BIG_ENDIAN = 0 - } grub_zfs_endian_t; - -#define grub_zfs_to_cpu16(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu16(x) \ +#define grub_zfs_to_cpu16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_be_to_cpu16(x) \ : grub_le_to_cpu16(x)) -#define grub_cpu_to_zfs16(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be16(x) \ +#define grub_cpu_to_zfs16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_cpu_to_be16(x) \ : grub_cpu_to_le16(x)) -#define grub_zfs_to_cpu32(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu32(x) \ +#define grub_zfs_to_cpu32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_be_to_cpu32(x) \ : grub_le_to_cpu32(x)) -#define grub_cpu_to_zfs32(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be32(x) \ +#define grub_cpu_to_zfs32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_cpu_to_be32(x) \ : grub_cpu_to_le32(x)) -#define grub_zfs_to_cpu64(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu64(x) \ +#define grub_zfs_to_cpu64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) \ + ? grub_be_to_cpu64(x) \ : grub_le_to_cpu64(x)) -#define grub_cpu_to_zfs64(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be64(x) \ +#define grub_cpu_to_zfs64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? grub_cpu_to_be64(x) \ : grub_cpu_to_le64(x)) /* diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 62b72776e..6c280bfe2 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -24,6 +24,14 @@ #include #include +#include + +typedef enum grub_zfs_endian + { + GRUB_ZFS_UNKNOWN_ENDIAN = -2, + GRUB_ZFS_LITTLE_ENDIAN = -1, + GRUB_ZFS_BIG_ENDIAN = 0 + } grub_zfs_endian_t; /* * On-disk version number. @@ -124,4 +132,17 @@ int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); #define GRUB_ZFS_MAX_KEYLEN 32 +extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian); + +struct grub_zfs_key; + +extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, + grub_size_t keysize); + + + #endif /* ! GRUB_ZFS_HEADER */ From ed746949afec9a9ab8c231e3ed4e49cefbe7c4f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 16:30:52 +0100 Subject: [PATCH 161/315] ZFS passphrase support --- grub-core/fs/zfs/zfs.c | 36 +++++++++++++++++++--- grub-core/fs/zfs/zfscrypt.c | 61 ++++++++++++++++++++++++------------- include/grub/zfs/zfs.h | 9 ++++-- util/grub-fstest.c | 20 ++++++++---- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3558bd8bb..0e9869d3f 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -205,7 +205,8 @@ grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) = NULL; grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize) = NULL; + grub_size_t keysize, + grub_uint64_t salt) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -1500,7 +1501,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (encrypted) { if (!grub_zfs_decrypt) - err = grub_error (GRUB_ERR_BAD_FS, "zfscrypto module not loaded"); + err = grub_error (GRUB_ERR_BAD_FS, "zfscrypt module not loaded"); else err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], compbuf, psize, ((grub_uint32_t *) &zc + 5), @@ -2657,8 +2658,10 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, const char *ptr_at, *filename; grub_uint64_t headobj; grub_uint64_t keychainobj; + grub_uint64_t salt; grub_err_t err; + auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, const void *val_in, grub_size_t nelem, @@ -2675,7 +2678,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, return 0; } - subvol->cipher = grub_zfs_load_key (val_in, nelem); + subvol->cipher = grub_zfs_load_key (val_in, nelem, salt); return 0; } @@ -2745,7 +2748,32 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); if (grub_zfs_load_key && keychainobj) { - dnode_end_t keychain_dn; + dnode_end_t keychain_dn, props_dn; + grub_uint64_t propsobj; + propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian); + + err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS, + &props_dn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + + err = zap_lookup (&props_dn, "salt", &salt, data, 0); + if (err == GRUB_ERR_FILE_NOT_FOUND) + { + err = 0; + grub_errno = 0; + salt = 0; + } + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return err; + } + err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, &keychain_dn, data); if (err) diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 251538041..d8c7181f0 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -64,19 +64,27 @@ struct grub_zfs_key struct grub_zfs_wrap_key { struct grub_zfs_wrap_key *next; - grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; + grub_size_t keylen; + int is_passphrase; + grub_uint64_t key[0]; }; static struct grub_zfs_wrap_key *zfs_wrap_keys; grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in) +grub_zfs_add_key (grub_uint8_t *key_in, + grub_size_t keylen, + int passphrase) { struct grub_zfs_wrap_key *key; - key = grub_malloc (sizeof (*key)); + if (!passphrase && keylen > 32) + keylen = 32; + key = grub_malloc (sizeof (*key) + keylen); if (!key) return grub_errno; - grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->is_passphrase = passphrase; + key->keylen = keylen; + grub_memcpy (key->key, key_in, keylen); key->next = zfs_wrap_keys; zfs_wrap_keys = key; return GRUB_ERR_NONE; @@ -168,7 +176,8 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, static grub_crypto_cipher_handle_t grub_zfs_load_key_real (const struct grub_zfs_key *key, - grub_size_t keysize) + grub_size_t keysize, + grub_uint64_t salt) { unsigned keylen; struct grub_zfs_wrap_key *wrap_key; @@ -192,15 +201,25 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) { grub_crypto_cipher_handle_t cipher; - grub_uint8_t decrypted[32], mac[32]; + grub_uint8_t decrypted[32], mac[32], wrap_key_real[32]; cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); if (!cipher) { grub_errno = GRUB_ERR_NONE; return 0; } - err = grub_crypto_cipher_set_key (cipher, - (const grub_uint8_t *) wrap_key->key, + grub_memset (wrap_key_real, 0, sizeof (wrap_key_real)); + if (!wrap_key->is_passphrase) + grub_memcpy(wrap_key_real, wrap_key->key, + wrap_key->keylen < keylen ? wrap_key->keylen : keylen); + else + grub_crypto_pbkdf2 (GRUB_MD_SHA1, + (const grub_uint8_t *) wrap_key->key, + wrap_key->keylen, + (const grub_uint8_t *) &salt, sizeof (salt), + 1000, wrap_key_real, keylen); + + err = grub_crypto_cipher_set_key (cipher, wrap_key_real, keylen); if (err) { @@ -268,25 +287,19 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) if (real_size < 0) return grub_errno; } - if (ctxt->state[0].set - || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + else { - grub_err_t err; - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; + grub_printf ("Enter ZFS password: "); + if (!grub_password_get ((char *) buf, 1023)) + return grub_errno; + real_size = grub_strlen ((char *) buf); } if (ctxt->state[1].set) { int i; grub_err_t err; - if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); - for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + for (i = 0; i < real_size / 2; i++) { char c1 = grub_tolower (buf[2 * i]) - '0'; char c2 = grub_tolower (buf[2 * i + 1]) - '0'; @@ -296,12 +309,16 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) c2 += '0' - 'a' + 10; buf[i] = (c1 << 4) | c2; } - err = grub_zfs_add_key (buf); + err = grub_zfs_add_key (buf, real_size / 2, 0); if (err) return err; return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; + + return grub_zfs_add_key (buf, real_size, + ctxt->state[2].set + || (argc == 0 && !ctxt->state[0].set + && !ctxt->state[1].set)); } static grub_extcmd_t cmd_key; diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 6c280bfe2..db8e915bf 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -129,8 +129,10 @@ char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, grub_size_t index); int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, const char *name); -grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); -#define GRUB_ZFS_MAX_KEYLEN 32 +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in, + grub_size_t keylen, + int passphrase); extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, void *nonce, @@ -141,7 +143,8 @@ extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, struct grub_zfs_key; extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize); + grub_size_t keysize, + grub_uint64_t salt); diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 0d0801187..f90755e86 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -439,7 +439,7 @@ static struct argp_option options[] = { {"diskcount", 'c', "N", 0, N_("N input files."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, - {"zfs-key-file", 'K', N_("KEY_FILENAME"), 0, N_("Load zfs crypto key."), 2}, + {"zfs-key", 'K', N_("FILE|prompt"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {"uncompress", 'u', NULL, OPTION_ARG_OPTIONAL, N_("Uncompress data."), 2}, {0, 0, 0, 0, 0, 0} @@ -465,26 +465,34 @@ argp_parser (int key, char *arg, struct argp_state *state) return 0; case 'K': + if (strcmp (arg, "prompt") == 0) + { + char buf[1024]; + grub_printf ("Enter ZFS password: "); + if (grub_password_get (buf, 1023)) + { + grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); + } + } + else { FILE *f; ssize_t real_size; - grub_uint8_t buf[GRUB_ZFS_MAX_KEYLEN]; + grub_uint8_t buf[1024]; f = fopen (arg, "rb"); if (!f) { printf ("Error loading file %s: %s\n", arg, strerror (errno)); return 0; } - real_size = fread (buf, 1, GRUB_ZFS_MAX_KEYLEN, f); + real_size = fread (buf, 1, 1024, f); if (real_size < 0) { printf ("Error loading file %s: %s\n", arg, strerror (errno)); fclose (f); return 0; } - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - grub_zfs_add_key (buf); + grub_zfs_add_key (buf, real_size, 0); } return 0; From d99b3726e591f125220fba02725bfe9fcbfb424b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 17:13:38 +0100 Subject: [PATCH 162/315] Support ZFS subvolumes with multiple keys --- grub-core/fs/zfs/zfs.c | 132 ++++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 27 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 0e9869d3f..6ab1f61a7 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -167,7 +167,12 @@ struct subvolume dnode_end_t mdn; grub_uint64_t obj; grub_uint64_t case_insensitive; - grub_crypto_cipher_handle_t cipher; + grub_size_t nkeys; + struct + { + grub_crypto_cipher_handle_t cipher; + grub_uint64_t txg; + } *keyring; }; struct grub_zfs_data @@ -1503,9 +1508,37 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (!grub_zfs_decrypt) err = grub_error (GRUB_ERR_BAD_FS, "zfscrypt module not loaded"); else - err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], - compbuf, psize, ((grub_uint32_t *) &zc + 5), - endian); + { + unsigned i, besti = 0; + grub_uint64_t bestval = 0; + for (i = 0; i < data->subvol.nkeys; i++) + if (data->subvol.keyring[i].txg <= grub_zfs_to_cpu64 (bp->blk_birth, + endian) + && data->subvol.keyring[i].txg > bestval) + { + besti = i; + bestval = data->subvol.keyring[i].txg; + } + if (bestval == 0) + { + grub_free (compbuf); + *buf = NULL; + grub_dprintf ("zfs", "no key for txg %" PRIxGRUB_UINT64_T "\n", + grub_zfs_to_cpu64 (bp->blk_birth, + endian)); + return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain"); + } + grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T + ", %p) for txg %" PRIxGRUB_UINT64_T "\n", + besti, data->subvol.keyring[besti].txg, + data->subvol.keyring[besti].cipher, + grub_zfs_to_cpu64 (bp->blk_birth, + endian)); + err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher, + &(bp)->blk_dva[encrypted], + compbuf, psize, ((grub_uint32_t *) &zc + 5), + endian); + } if (err) { grub_free (compbuf); @@ -1896,7 +1929,9 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* XXX */ static int fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, - int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_size_t name_elem_length, + int NESTED_FUNC_ATTR (*hook) (const void *name, + grub_size_t name_length, const void *val_in, grub_size_t nelem, grub_size_t elemsize), @@ -1971,18 +2006,19 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, if (le->le_type != ZAP_CHUNK_ENTRY) continue; - buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) - + 1); + buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + * name_elem_length + 1); if (zap_leaf_array_get (l, endian, blksft, grub_zfs_to_cpu16 (le->le_name_chunk, endian), grub_zfs_to_cpu16 (le->le_name_length, - endian), buf)) + endian) + * name_elem_length, buf)) { grub_free (buf); continue; } - buf[le->le_name_length] = 0; + buf[le->le_name_length * name_elem_length] = 0; val_length = ((int) le->le_value_length * (int) le->le_int_size); @@ -1997,7 +2033,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, continue; } - if (hook (buf, val, le->le_value_length, le->le_int_size)) + if (hook (buf, le->le_name_length, + val, le->le_value_length, le->le_int_size)) return 1; grub_free (buf); grub_free (val); @@ -2069,12 +2106,14 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, int ret; grub_zfs_endian_t endian; - auto int NESTED_FUNC_ATTR transform (const char *name, + auto int NESTED_FUNC_ATTR transform (const void *name, + grub_size_t namelen, const void *val_in, grub_size_t nelem, grub_size_t elemsize); - int NESTED_FUNC_ATTR transform (const char *name, + int NESTED_FUNC_ATTR transform (const void *name, + grub_size_t namelen __attribute__ ((unused)), const void *val_in, grub_size_t nelem, grub_size_t elemsize) @@ -2104,7 +2143,7 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, transform, data); + ret = fzap_iterate (zap_dnode, zapbuf, 1, transform, data); grub_free (zapbuf); return ret; } @@ -2114,7 +2153,9 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, static int zap_iterate (dnode_end_t * zap_dnode, - int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_size_t nameelemlen, + int NESTED_FUNC_ATTR (*hook) (const void *name, + grub_size_t namelen, const void *val_in, grub_size_t nelem, grub_size_t elemsize), @@ -2145,7 +2186,7 @@ zap_iterate (dnode_end_t * zap_dnode, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, hook, data); + ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, data); grub_free (zapbuf); return ret; } @@ -2660,17 +2701,41 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_uint64_t keychainobj; grub_uint64_t salt; grub_err_t err; + int keyn = 0; - - auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, - const void *val_in, - grub_size_t nelem, - grub_size_t elemsize); - int NESTED_FUNC_ATTR iterate_zap_key (const char *name __attribute__ ((unused)), - const void *val_in, - grub_size_t nelem, - grub_size_t elemsize) + auto int NESTED_FUNC_ATTR count_zap_keys (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR count_zap_keys (const void *name __attribute__ ((unused)), + grub_size_t namelen __attribute__ ((unused)), + const void *val_in __attribute__ ((unused)), + grub_size_t nelem __attribute__ ((unused)), + grub_size_t elemsize __attribute__ ((unused))) { + subvol->nkeys++; + return 0; + } + + auto int NESTED_FUNC_ATTR load_zap_key (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR load_zap_key (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + if (namelen != 1) + { + grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n", + namelen); + return 0; + } + if (elemsize != 1) { grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", @@ -2678,7 +2743,9 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, return 0; } - subvol->cipher = grub_zfs_load_key (val_in, nelem, salt); + subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name); + subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt); + keyn++; return 0; } @@ -2782,7 +2849,16 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_free (snapname); return err; } - zap_iterate (&keychain_dn, iterate_zap_key, data); + subvol->nkeys = 0; + zap_iterate (&keychain_dn, 8, count_zap_keys, data); + subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); + if (!subvol->keyring) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + zap_iterate (&keychain_dn, 8, load_zap_key, data); } if (snapname) @@ -3087,7 +3163,9 @@ zfs_unmount (struct grub_zfs_data *data) grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); - grub_crypto_cipher_close (data->subvol.cipher); + for (i = 0; i < data->subvol.nkeys; i++) + grub_crypto_cipher_close (data->subvol.keyring[i].cipher); + grub_free (data->subvol.keyring); grub_free (data); } From bc1de0bc26ad95dd81b968fa75eaae92023bcb18 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 21:05:25 +0100 Subject: [PATCH 163/315] GCM support --- grub-core/fs/zfs/zfs.c | 10 ++- grub-core/fs/zfs/zfscrypt.c | 147 +++++++++++++++++++++++++++++++++--- include/grub/zfs/zfs.h | 4 +- 3 files changed, 147 insertions(+), 14 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 6ab1f61a7..fcf32d9db 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -172,6 +172,7 @@ struct subvolume { grub_crypto_cipher_handle_t cipher; grub_uint64_t txg; + grub_uint64_t algo; } *keyring; }; @@ -205,13 +206,15 @@ struct grub_zfs_data }; grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) = NULL; grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt) = NULL; + grub_uint64_t salt, + grub_uint64_t algo) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -1535,6 +1538,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, grub_zfs_to_cpu64 (bp->blk_birth, endian)); err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher, + data->subvol.keyring[besti].algo, &(bp)->blk_dva[encrypted], compbuf, psize, ((grub_uint32_t *) &zc + 5), endian); @@ -2744,7 +2748,9 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, } subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name); - subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt); + subvol->keyring[keyn].algo = grub_le_to_cpu64 (*(grub_uint64_t *) val_in); + subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt, + subvol->keyring[keyn].algo); keyn++; return 0; } diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index d8c7181f0..39335a728 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -141,8 +141,132 @@ grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, return GRUB_ERR_NONE; } +static void +grub_gcm_mul_x (grub_uint8_t *a) +{ + int i; + int c = 0, d = 0; + for (i = 0; i < 16; i++) + { + c = a[i] & 0x1; + a[i] = (a[i] >> 1) | (d << 7); + d = c; + } + if (d) + a[0] ^= 0xe1; +} + +static void +grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) +{ + grub_uint8_t res[16], bs[16]; + int i; + grub_memcpy (bs, b, 16); + grub_memset (res, 0, 16); + for (i = 0; i < 128; i++) + { + if ((a[i / 8] << (i % 8)) & 0x80) + grub_crypto_xor (res, res, bs, 16); + grub_gcm_mul_x (bs); + } + + grub_memcpy (a, res, 16); +} + static grub_err_t -grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, +grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned nonce_len, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint8_t mac[16], h[16], mac_xor[16]; + unsigned i, j; + grub_err_t err; + + grub_memset (mac, 0, sizeof (mac)); + + err = grub_crypto_ecb_encrypt (cipher, h, mac, 16); + if (err) + return err; + + if (nonce_len == 12) + { + grub_memcpy (iv, nonce, 12); + iv[12] = 0; + iv[13] = 0; + iv[14] = 0; + iv[15] = 1; + } + else + { + grub_memset (iv, 0, sizeof (iv)); + grub_memcpy (iv, nonce, nonce_len); + grub_gcm_mul (iv, h); + iv[15] ^= nonce_len * 8; + grub_gcm_mul (iv, h); + } + + err = grub_crypto_ecb_encrypt (cipher, mac_xor, iv, 16); + if (err) + return err; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < 4; j++) + { + iv[15 - j]++; + if (iv[15 - j] != 0) + break; + } + grub_crypto_xor (mac, mac, in + 16 * i, csize); + grub_gcm_mul (mac, h); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + } + for (j = 0; j < 8; j++) + mac[15 - j] ^= ((psize * 8) >> (8 * j)); + grub_gcm_mul (mac, h); + + if (mac_out) + grub_crypto_xor (mac_out, mac, mac_xor, m); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + switch (algo) + { + case 0: + return grub_ccm_decrypt (cipher, out, in, psize, mac_out, nonce, l, m); + case 1: + return grub_gcm_decrypt (cipher, out, in, psize, mac_out, nonce, + 15 - l, m); + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "algorithm %" + PRIuGRUB_UINT64_T " is not supported yet", algo); + } +} + +static grub_err_t +grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, + void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) @@ -159,11 +283,11 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, if (!cipher) return grub_error (GRUB_ERR_ACCESS_DENIED, "no decryption key available");; - err = grub_ccm_decrypt (cipher, - (grub_uint8_t *) buf, - (grub_uint8_t *) buf, - size, mac, - sw + 1, 3, 12); + err = algo_decrypt (cipher, algo, + (grub_uint8_t *) buf, + (grub_uint8_t *) buf, + size, mac, + sw + 1, 3, 12); if (err) return err; @@ -177,7 +301,8 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, static grub_crypto_cipher_handle_t grub_zfs_load_key_real (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt) + grub_uint64_t salt, + grub_uint64_t algo) { unsigned keylen; struct grub_zfs_wrap_key *wrap_key; @@ -227,8 +352,8 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, continue; } - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); + err = algo_decrypt (cipher, algo, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0)) { @@ -237,8 +362,8 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, continue; } - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); + err = algo_decrypt (cipher, algo, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) { grub_dprintf ("zfs", "key loading failed\n"); diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index db8e915bf..e326c8b2f 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -135,6 +135,7 @@ grub_zfs_add_key (grub_uint8_t *key_in, int passphrase); extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, @@ -144,7 +145,8 @@ struct grub_zfs_key; extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt); + grub_uint64_t salt, + grub_uint64_t algo); From ae9a20d973284a143e798e06d292c63a1b3a793e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 21:08:32 +0100 Subject: [PATCH 164/315] Small cleanup --- grub-core/fs/zfs/zfs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index fcf32d9db..4d9a474fb 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1479,6 +1479,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (comp != ZIO_COMPRESS_OFF) { + /* It's not really necessary to align to 16, just for safety. */ compbuf = grub_malloc (ALIGN_UP (psize, 16)); if (! compbuf) return grub_errno; @@ -1878,9 +1879,6 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); - /* if (zap->zap_flags != 0) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags");*/ - if (zap->zap_salt == 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); From ed64e9e27954718192e598d1f4bfaf0caba38152 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 11:23:56 +0100 Subject: [PATCH 165/315] Support trampoline jumps on powerpc. * grub-core/kern/dl.c (grub_dl_load_segments) [__powerpc__]: Follow __ia64__ path. (grub_dl_load_segments): Set mod->sz. (grub_dl_flush_cache): Flush whole space occupied by module, not just segments. * grub-core/kern/ia64/dl.c (nopm): Make const while on it. (jump): Likewise. * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): New function. (trampoline): New struct. (trampoline_template): New const. (grub_arch_dl_relocate_symbols): Create trampolines on overflow. * include/grub/dl.h (grub_dl): Add sz element. [__powerpc__]: Follow __ia64__. (GRUB_ARCH_DL_TRAMP_ALIGN): Define on ppc. (GRUB_ARCH_DL_GOT_ALIGN): Likewise. (GRUB_ARCH_DL_TRAMP_SIZE): Likewise. (grub_arch_dl_get_tramp_got_size) [__powerpc__]: New proto. --- ChangeLog | 23 ++++++++++++ grub-core/kern/dl.c | 21 ++++------- grub-core/kern/ia64/dl.c | 4 +- grub-core/kern/powerpc/dl.c | 75 ++++++++++++++++++++++++++++++++++++- include/grub/dl.h | 15 +++++++- 5 files changed, 120 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 891126792..48799984d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2011-11-08 Vladimir Serbinenko + + Support trampoline jumps on powerpc. + + * grub-core/kern/dl.c (grub_dl_load_segments) [__powerpc__]: Follow + __ia64__ path. + (grub_dl_load_segments): Set mod->sz. + (grub_dl_flush_cache): Flush whole space occupied by module, not just + segments. + * grub-core/kern/ia64/dl.c (nopm): Make const while on it. + (jump): Likewise. + * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): New + function. + (trampoline): New struct. + (trampoline_template): New const. + (grub_arch_dl_relocate_symbols): Create trampolines on overflow. + * include/grub/dl.h (grub_dl): Add sz element. + [__powerpc__]: Follow __ia64__. + (GRUB_ARCH_DL_TRAMP_ALIGN): Define on ppc. + (GRUB_ARCH_DL_GOT_ALIGN): Likewise. + (GRUB_ARCH_DL_TRAMP_SIZE): Likewise. + (grub_arch_dl_get_tramp_got_size) [__powerpc__]: New proto. + 2011-11-06 Vladimir Serbinenko ZFS crypto support. diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 1841bf1f5..b6fb537e8 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -233,7 +233,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) unsigned i; Elf_Shdr *s; grub_size_t tsize = 0, talign = 1; -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) grub_size_t tramp; grub_size_t got; #endif @@ -248,9 +248,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) talign = s->sh_addralign; } -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - tramp *= GRUB_IA64_DL_TRAMP_SIZE; + tramp *= GRUB_ARCH_DL_TRAMP_SIZE; got *= sizeof (grub_uint64_t); tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) @@ -269,6 +269,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->base = grub_memalign (talign, tsize); if (!mod->base) return grub_errno; + mod->sz = tsize; ptr = mod->base; #ifdef GRUB_MACHINE_EMU @@ -316,7 +317,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); mod->tramp = ptr; ptr += tramp; @@ -575,15 +576,9 @@ grub_dl_unref (grub_dl_t mod) static void grub_dl_flush_cache (grub_dl_t mod) { - grub_dl_segment_t seg; - - for (seg = mod->segment; seg; seg = seg->next) { - if (seg->size) { - grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", - (unsigned long) seg->size, seg->addr); - grub_arch_sync_caches (seg->addr, seg->size); - } - } + grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", + (unsigned long) mod->sz, mod->base); + grub_arch_sync_caches (mod->base, mod->sz); } /* Load a module from core memory. */ diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 3904f73b7..31b5f94cf 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -104,13 +104,13 @@ add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) } } -static grub_uint8_t nopm[5] = +static const grub_uint8_t nopm[5] = { /* [MLX] nop.m 0x0 */ 0x05, 0x00, 0x00, 0x00, 0x01 }; -static grub_uint8_t jump[0x20] = +static const grub_uint8_t jump[0x20] = { /* ld8 r16=[r15],8 */ 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c index ad19e5600..34e780a45 100644 --- a/grub-core/kern/powerpc/dl.c +++ b/grub-core/kern/powerpc/dl.c @@ -37,6 +37,65 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + *tramp = 0; + *got = 0; + + /* Find a symbol table. */ + for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return; + + entsize = s->sh_entsize; + + for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + const Elf_Rela *rel, *max; + + for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + if (ELF_R_TYPE (rel->r_info) == R_PPC_REL24) + (*tramp)++; + + } + + return; +} + +/* For low-endian reverse lis and addr_high as well as ori and addr_low. */ +struct trampoline +{ + grub_uint32_t lis; + grub_uint32_t ori; + grub_uint32_t mtctr; + grub_uint32_t bctr; +}; + +static const struct trampoline trampoline_template = + { + 0x3c000000, + 0x60000000, + 0x7c0903a6, + 0x4e800420, + }; /* Relocate symbols. */ grub_err_t @@ -46,6 +105,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Shdr *s; Elf_Word entsize; unsigned i; + struct trampoline *tptr = mod->tramp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -106,7 +166,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Sword delta = value - (Elf_Word) addr; if (delta << 6 >> 6 != delta) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); + { + COMPILE_TIME_ASSERT (sizeof (struct trampoline) + == GRUB_ARCH_DL_TRAMP_SIZE); + grub_memcpy (tptr, &trampoline_template, + sizeof (*tptr)); + delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; + tptr->lis |= (((value) >> 16) & 0xffff); + tptr->ori |= ((value) & 0xffff); + tptr++; + } + + if (delta << 6 >> 6 != delta) + return grub_error (GRUB_ERR_BAD_MODULE, + "relocation overflow"); *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); break; } diff --git a/include/grub/dl.h b/include/grub/dl.h index 75cd71758..886e966cc 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -136,11 +136,12 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) void *got; void *tramp; #endif void *base; + grub_size_t sz; struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -176,10 +177,20 @@ void grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); -#ifdef __ia64__ +#if defined (__ia64__) #define GRUB_ARCH_DL_TRAMP_ALIGN 16 #define GRUB_ARCH_DL_GOT_ALIGN 16 #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size +#else +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +#endif + +#ifdef __powerpc__ +#define GRUB_ARCH_DL_TRAMP_SIZE 16 +#define GRUB_ARCH_DL_TRAMP_ALIGN 4 +#define GRUB_ARCH_DL_GOT_ALIGN 4 #endif #endif From 9f421dd1f07e7be1b6dfbad162d44bcd5c57916a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 11:32:19 +0100 Subject: [PATCH 166/315] * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used variable. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48799984d..dd8a9858d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used + variable. + 2011-11-08 Vladimir Serbinenko Support trampoline jumps on powerpc. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4d9a474fb..fb16a009b 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -2164,14 +2164,12 @@ zap_iterate (dnode_end_t * zap_dnode, struct grub_zfs_data *data) { grub_uint64_t block_type; - int size; void *zapbuf; grub_err_t err; int ret; grub_zfs_endian_t endian; /* Read in the first block of the zap object data. */ - size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); if (err) return 0; From 78e08dc3cb36e163b2a1e96bf828c1ed0ae9f323 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:06:27 +0100 Subject: [PATCH 167/315] * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. --- ChangeLog | 4 ++++ util/grub.d/10_kfreebsd.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dd8a9858d..02af51ea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-08 Vladimir Serbinenko + + * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. + 2011-11-08 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index e668f3fd9..a1b86b82b 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -160,7 +160,7 @@ while [ "x$list" != "x" ] ; do # zpool name kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) # filesystem name (empty string for the main filesystem) - kfreebsd_device="${kfreebsd_device}$(grub-mkrelpath / | sed -e "s,/*@$,,")" + kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")" ;; *) kfreebsd_device=${kfreebsd_fs}id/${GRUB_DEVICE_UUID} From cac14fb663e637f8bb944cb3aab16ce9040840b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:15:57 +0100 Subject: [PATCH 168/315] Support escaped commas in hostdisk. * grub-core/kern/emu/hostdisk.c (unescape_cmp): New function. (find_grub_drive): Use unescape_cmp. (make_device_name): Escape commas. --- ChangeLog | 8 +++++ grub-core/kern/emu/hostdisk.c | 58 +++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02af51ea8..c7f8d3c7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-08 Vladimir Serbinenko + + Support escaped commas in hostdisk. + + * grub-core/kern/emu/hostdisk.c (unescape_cmp): New function. + (find_grub_drive): Use unescape_cmp. + (make_device_name): Escape commas. + 2011-11-08 Vladimir Serbinenko * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 23417a64d..4d5c28631 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -184,6 +184,27 @@ configure_device_driver (int fd) } #endif /* defined(__NetBSD__) */ +static int +unescape_cmp (const char *a, const char *b_escaped) +{ + while (*a || *b_escaped) + { + if (*b_escaped == '\\' && b_escaped[1] != 0) + b_escaped++; + if (*a < *b_escaped) + return -1; + if (*a > *b_escaped) + return +1; + a++; + b_escaped++; + } + if (*a) + return +1; + if (*b_escaped) + return -1; + return 0; +} + static int find_grub_drive (const char *name) { @@ -192,7 +213,7 @@ find_grub_drive (const char *name) if (name) { for (i = 0; i < ARRAY_SIZE (map); i++) - if (map[i].drive && ! strcmp (map[i].drive, name)) + if (map[i].drive && unescape_cmp (map[i].drive, name) == 0) return i; } @@ -1140,25 +1161,28 @@ grub_util_biosdisk_fini (void) static char * make_device_name (int drive, int dos_part, int bsd_part) { - char *ret; - char *dos_part_str = NULL; - char *bsd_part_str = NULL; + char *ret, *ptr, *end; + const char *iptr; + ret = xmalloc (strlen (map[drive].drive) * 2 + + sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX" + ",XXXXXXXXXXXXXXXXXXXXXXXXXX")); + end = (ret + strlen (map[drive].drive) * 2 + + sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX" + ",XXXXXXXXXXXXXXXXXXXXXXXXXX")); + ptr = ret; + for (iptr = map[drive].drive; *iptr; iptr++) + { + if (*iptr == ',') + *ptr++ = '\\'; + *ptr++ = *iptr; + } + *ptr = 0; if (dos_part >= 0) - dos_part_str = xasprintf (",%d", dos_part + 1); - + snprintf (ptr, end - ptr, ",%d", dos_part + 1); + ptr += strlen (ptr); if (bsd_part >= 0) - bsd_part_str = xasprintf (",%d", bsd_part + 1); - - ret = xasprintf ("%s%s%s", map[drive].drive, - dos_part_str ? : "", - bsd_part_str ? : ""); - - if (dos_part_str) - free (dos_part_str); - - if (bsd_part_str) - free (bsd_part_str); + snprintf (ptr, end - ptr, ",%d", bsd_part + 1); return ret; } From 958ee2216874b6587ff0534fa7030e06a58167ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:38:30 +0100 Subject: [PATCH 169/315] Illumos support. * Makefile.util.def (10_illumos): New script. * configure.ac: Set COND_HOST_ILLUMOS. * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__sun__]: Support Illumos calls. (find_partition_start) [__sun__]: Likewise. (convert_system_partition_to_system_disk) [__sun__]: Likewise. (device_is_wholedisk) [__sun__]: Handle Illumos naming scheme. (grub_util_biosdisk_get_grub_dev) [__sun__]: Handle Illumos. * util/getroot.c (find_root_device_from_libzfs) [__sun__]: Return raw device. * util/grub-probe.c (probe) [__sun__]: Do character check. * util/grub.d/10_illumos.in: New file. --- ChangeLog | 17 +++++++++ Makefile.util.def | 7 ++++ configure.ac | 2 + grub-core/kern/emu/hostdisk.c | 72 +++++++++++++++++++++++++++++------ util/getroot.c | 19 ++++++++- util/grub-probe.c | 2 +- util/grub.d/10_illumos.in | 54 ++++++++++++++++++++++++++ 7 files changed, 159 insertions(+), 14 deletions(-) create mode 100644 util/grub.d/10_illumos.in diff --git a/ChangeLog b/ChangeLog index c7f8d3c7b..edb0b2c10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-11-08 Vladimir Serbinenko + + Illumos support. + + * Makefile.util.def (10_illumos): New script. + * configure.ac: Set COND_HOST_ILLUMOS. + * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__sun__]: + Support Illumos calls. + (find_partition_start) [__sun__]: Likewise. + (convert_system_partition_to_system_disk) [__sun__]: Likewise. + (device_is_wholedisk) [__sun__]: Handle Illumos naming scheme. + (grub_util_biosdisk_get_grub_dev) [__sun__]: Handle Illumos. + * util/getroot.c (find_root_device_from_libzfs) [__sun__]: Return raw + device. + * util/grub-probe.c (probe) [__sun__]: Do character check. + * util/grub.d/10_illumos.in: New file. + 2011-11-08 Vladimir Serbinenko Support escaped commas in hostdisk. diff --git a/Makefile.util.def b/Makefile.util.def index 15a309367..8742d1583 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -367,6 +367,13 @@ script = { condition = COND_HOST_KFREEBSD; }; +script = { + name = '10_illumos'; + common = util/grub.d/10_illumos.in; + installdir = grubconf; + condition = COND_HOST_ILLUMOS; +}; + script = { name = '10_netbsd'; common = util/grub.d/10_netbsd.in; diff --git a/configure.ac b/configure.ac index 6aafdf13d..e707081a7 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,7 @@ case "$host_os" in linux*) host_kernel=linux ;; freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;; netbsd*) host_kernel=netbsd ;; + solaris*) host_kernel=illumos ;; cygwin) host_kernel=windows ;; esac @@ -974,6 +975,7 @@ AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd]) AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows]) AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd]) +AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 4d5c28631..7074fa8c1 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -98,6 +98,10 @@ struct hd_geometry # define FLOPPY_MAJOR 2 #endif +#if defined (__sun__) +# include +#endif + #if defined(__APPLE__) # include #endif @@ -252,11 +256,11 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), grub_uint64_t grub_util_get_fd_sectors (int fd, unsigned *log_secsize) { -#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) # if defined(__NetBSD__) struct disklabel label; -# else +# elif defined (__sun__) + struct dk_minfo minfo; +#else unsigned long long nr; # endif unsigned sector_size, log_sector_size; @@ -265,7 +269,11 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) if (fstat (fd, &st) < 0) grub_util_error ("fstat failed"); -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) \ + || defined (__sun__) + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) # else if (! S_ISBLK (st.st_mode)) @@ -279,6 +287,8 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # elif defined(__NetBSD__) configure_device_driver (fd); if (ioctl (fd, DIOCGDINFO, &label) == -1) +# elif defined (__sun__) + if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo)) # else if (ioctl (fd, BLKGETSIZE64, &nr)) # endif @@ -287,13 +297,14 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (ioctl (fd, DIOCGSECTORSIZE, §or_size)) goto fail; +# elif defined(__sun__) + sector_size = minfo.dki_lbsize; # elif defined(__NetBSD__) sector_size = label.d_secsize; # else if (ioctl (fd, BLKSSZGET, §or_size)) goto fail; # endif - if (sector_size & (sector_size - 1) || !sector_size) goto fail; for (log_sector_size = 0; @@ -307,6 +318,8 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) return nr; # elif defined(__NetBSD__) return label.d_secperunit; +# elif defined (__sun__) + return minfo.dki_capacity; # else if (nr & ((1 << log_sector_size) - 1)) grub_util_error ("unaligned device size"); @@ -315,11 +328,15 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # endif fail: + /* In GNU/Hurd, stat() will return the right size. */ #elif !defined (__GNU__) # warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." #endif + sector_size = 512; + log_sector_size = 9; + if (log_secsize) *log_secsize = 9; @@ -419,12 +436,14 @@ find_partition_start (const char *dev) return out; } -#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) +#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined (__sun__) static grub_disk_addr_t find_partition_start (const char *dev) { int fd; -# if !defined(HAVE_DIOCGDINFO) +#ifdef __sun__ + struct extpart_info pinfo; +# elif !defined(HAVE_DIOCGDINFO) struct hd_geometry hdg; # else /* defined(HAVE_DIOCGDINFO) */ struct disklabel label; @@ -511,7 +530,9 @@ devmapper_fail: return 0; } -# if !defined(HAVE_DIOCGDINFO) +#if defined(__sun__) + if (ioctl (fd, DKIOCEXTPARTINFO, &pinfo)) +# elif !defined(HAVE_DIOCGDINFO) if (ioctl (fd, HDIO_GETGEO, &hdg)) # else /* defined(HAVE_DIOCGDINFO) */ # if defined(__NetBSD__) @@ -532,7 +553,9 @@ devmapper_fail: close (fd); -# if !defined(HAVE_DIOCGDINFO) +#ifdef __sun__ + return pinfo.p_start; +# elif !defined(HAVE_DIOCGDINFO) return hdg.start; # else /* defined(HAVE_DIOCGDINFO) */ if (dev[0]) @@ -1568,12 +1591,37 @@ devmapper_out: } return path; +#elif defined (__sun__) + char *colon = grub_strrchr (os_dev, ':'); + if (grub_memcmp (os_dev, "/devices", sizeof ("/devices") - 1) == 0 + && colon) + { + char *ret = xmalloc (colon - os_dev + sizeof (":q,raw")); + grub_memcpy (ret, os_dev, colon - os_dev); + grub_memcpy (ret + (colon - os_dev), ":q,raw", sizeof (":q,raw")); + return ret; + } + else + return xstrdup (os_dev); #else # warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly." return xstrdup (os_dev); #endif } +#if defined(__sun__) +static int +device_is_wholedisk (const char *os_dev) +{ + if (grub_memcmp (os_dev, "/devices/", sizeof ("/devices/") - 1) != 0) + return 1; + if (grub_memcmp (os_dev + strlen (os_dev) - (sizeof (":q,raw") - 1), + ":q,raw", (sizeof (":q,raw") - 1)) == 0) + return 1; + return 0; +} +#endif + #if defined(__linux__) || defined(__CYGWIN__) static int device_is_wholedisk (const char *os_dev) @@ -1700,14 +1748,14 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) #else if (! S_ISBLK (st.st_mode)) #endif return make_device_name (drive, -1, -1); -#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__) /* Linux counts partitions uniformly, whether a BSD partition or a DOS partition, so mapping them to GRUB devices is not trivial. @@ -1747,7 +1795,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) name = make_device_name (drive, -1, -1); -# if !defined(HAVE_DIOCGDINFO) +# if !defined(HAVE_DIOCGDINFO) && !defined(__sun__) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; # else /* defined(HAVE_DIOCGDINFO) */ diff --git a/util/getroot.c b/util/getroot.c index 3d6f9370c..8fce283bc 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -61,6 +61,11 @@ # include #endif +#ifdef __sun__ +# include +# include +#endif + #include #include #include @@ -289,7 +294,19 @@ find_root_device_from_libzfs (const char *dir) struct stat st; if (stat (device, &st) == 0) { - device = xstrdup (device); +#ifdef __sun__ + if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1) + == 0) + device = xasprintf ("/dev/rdsk/%s", + device + sizeof ("/dev/dsk/") - 1); + else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1) + == 0 + && grub_memcmp (device + strlen (device) - 4, + ",raw", 4) != 0) + device = xasprintf ("%s,raw", device); + else +#endif + device = xstrdup (device); break; } diff --git a/util/grub-probe.c b/util/grub-probe.c index ae58c89f3..54b9d03c6 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -171,7 +171,7 @@ probe (const char *path, char *device_name) if (path == NULL) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__) if (! grub_util_check_char_device (device_name)) grub_util_error ("%s is not a character device", device_name); #else diff --git a/util/grub.d/10_illumos.in b/util/grub.d/10_illumos.in new file mode 100644 index 000000000..2b87dfa4f --- /dev/null +++ b/util/grub.d/10_illumos.in @@ -0,0 +1,54 @@ +#! /bin/sh +set -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010,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 . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +datarootdir=@datarootdir@ +. ${libdir}/@PACKAGE@/grub-mkconfig_lib + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR=@localedir@ + +CLASS="--class os" + +case "${GRUB_DISTRIBUTOR}" in + *) + OS="Illumos" + CLASS="--class illumos ${CLASS}" + ;; +esac + +echo "menuentry '${OS}' ${CLASS} {" +save_default_entry | sed -e "s/^/\t/" +prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" +message="$(gettext_printf "Loading kernel of Illumos ...")" + cat << EOF + insmod gzio + if cpuid -l ; then + ISADIR=amd64 + else + ISADIR= + fi + zfs-bootfs $($grub_mkrelpath /) ZFS_BOOTFS + multiboot $($grub_mkrelpath /platform/i86pc/kernel)/\$ISADIR/unix /platform/i86pc/kernel/\$ISADIR/unix -B \$ZFS_BOOTFS,console=text + module $($grub_mkrelpath /platform/i86pc)/\$ISADIR/boot_archive /platform/i86pc/\$ISADIR/boot_archive +} +EOF From 4a19b6017d989c076b06861d3bfd6ba6d3fa9c75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 16:07:27 +0100 Subject: [PATCH 170/315] Fix ZFS crypto error types. * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Fix return type. (grub_gcm_decrypt): Likewise. (grub_zfs_load_key_real): Fix error code type. Handle possible error from PBKDF2. --- ChangeLog | 9 +++++++++ grub-core/fs/zfs/zfscrypt.c | 28 +++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index edb0b2c10..194bd13fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-08 Vladimir Serbinenko + + Fix ZFS crypto error types. + + * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Fix return type. + (grub_gcm_decrypt): Likewise. + (grub_zfs_load_key_real): Fix error code type. Handle possible error + from PBKDF2. + 2011-11-08 Vladimir Serbinenko Illumos support. diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 39335a728..14babd29f 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -90,7 +90,7 @@ grub_zfs_add_key (grub_uint8_t *key_in, return GRUB_ERR_NONE; } -static grub_err_t +static gcry_err_code_t grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -101,7 +101,7 @@ grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t mul[16]; grub_uint32_t mac[4]; unsigned i, j; - grub_err_t err; + gcry_err_code_t err; grub_memcpy (iv + 1, nonce, 15 - l); @@ -173,7 +173,7 @@ grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) grub_memcpy (a, res, 16); } -static grub_err_t +static gcry_err_code_t grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -184,7 +184,7 @@ grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t mul[16]; grub_uint8_t mac[16], h[16], mac_xor[16]; unsigned i, j; - grub_err_t err; + gcry_err_code_t err; grub_memset (mac, 0, sizeof (mac)); @@ -243,7 +243,7 @@ grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, } -static grub_err_t +static gcry_err_code_t algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -307,7 +307,6 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, unsigned keylen; struct grub_zfs_wrap_key *wrap_key; grub_crypto_cipher_handle_t ret = NULL; - grub_err_t err; if (keysize != sizeof (*key)) { @@ -327,6 +326,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, { grub_crypto_cipher_handle_t cipher; grub_uint8_t decrypted[32], mac[32], wrap_key_real[32]; + gcry_err_code_t err; cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); if (!cipher) { @@ -334,15 +334,21 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, return 0; } grub_memset (wrap_key_real, 0, sizeof (wrap_key_real)); + err = 0; if (!wrap_key->is_passphrase) grub_memcpy(wrap_key_real, wrap_key->key, wrap_key->keylen < keylen ? wrap_key->keylen : keylen); else - grub_crypto_pbkdf2 (GRUB_MD_SHA1, - (const grub_uint8_t *) wrap_key->key, - wrap_key->keylen, - (const grub_uint8_t *) &salt, sizeof (salt), - 1000, wrap_key_real, keylen); + err = grub_crypto_pbkdf2 (GRUB_MD_SHA1, + (const grub_uint8_t *) wrap_key->key, + wrap_key->keylen, + (const grub_uint8_t *) &salt, sizeof (salt), + 1000, wrap_key_real, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } err = grub_crypto_cipher_set_key (cipher, wrap_key_real, keylen); From 27610c3836e79f8c8d8838b8f3121924a9e60500 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:34:19 +0100 Subject: [PATCH 171/315] Fix FreeBSD compilation. * grub-core/disk/geli.c (GRUB_MD_SHA256) [GRUB_UTIL]: Redefine in a way to avoid circular dependency. (GRUB_MD_SHA512) [GRUB_UTIL]: Likewise. * util/getroot.c (grub_util_follow_gpart_up): Move from here... * grub-core/kern/emu/hostdisk.c (+grub_util_follow_gpart_up): ... here. --- ChangeLog | 10 +++++++ grub-core/disk/geli.c | 32 +++++++++++++++++++++ grub-core/kern/emu/hostdisk.c | 53 +++++++++++++++++++++++++++++++++++ util/getroot.c | 50 --------------------------------- 4 files changed, 95 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 194bd13fa..925b798bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-08 Vladimir Serbinenko + + Fix FreeBSD compilation. + + * grub-core/disk/geli.c (GRUB_MD_SHA256) [GRUB_UTIL]: Redefine in a way + to avoid circular dependency. + (GRUB_MD_SHA512) [GRUB_UTIL]: Likewise. + * util/getroot.c (grub_util_follow_gpart_up): Move from here... + * grub-core/kern/emu/hostdisk.c (+grub_util_follow_gpart_up): ... here. + 2011-11-08 Vladimir Serbinenko Fix ZFS crypto error types. diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index d2ae5da56..ab94b4131 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -58,6 +58,38 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* Dirty trick to solve circular dependency. */ +#ifdef GRUB_UTIL + +#include + +#undef GRUB_MD_SHA256 +#undef GRUB_MD_SHA512 + +static const gcry_md_spec_t * +grub_md_sha256_real (void) +{ + const gcry_md_spec_t *ret; + ret = grub_crypto_lookup_md_by_name ("sha256"); + if (!ret) + grub_util_error ("Coulnd't load sha256"); + return ret; +} + +static const gcry_md_spec_t * +grub_md_sha512_real (void) +{ + const gcry_md_spec_t *ret; + ret = grub_crypto_lookup_md_by_name ("sha512"); + if (!ret) + grub_util_error ("Coulnd't load sha512"); + return ret; +} + +#define GRUB_MD_SHA256 grub_md_sha256_real() +#define GRUB_MD_SHA512 grub_md_sha512_real() +#endif + struct grub_geli_key { grub_uint8_t iv_key[64]; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7074fa8c1..7bfc66fef 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -94,6 +94,8 @@ struct hd_geometry # include /* DIOCGMEDIASIZE */ # include # include +# include +#include # define MAJOR(dev) major(dev) # define FLOPPY_MAJOR 2 #endif @@ -423,8 +425,59 @@ grub_util_device_is_mapped (const char *dev) #endif /* HAVE_DEVICE_MAPPER */ } + #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +/* FIXME: geom actually gives us the whole container hierarchy. + It can be used more efficiently than this. */ +void +grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) +{ + struct gmesh mesh; + struct gclass *class; + int error; + struct ggeom *geom; + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + if (strcasecmp (class->lg_name, "part") == 0) + break; + if (!class) + grub_util_error ("couldn't open geom part"); + + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + char *name_tmp = xstrdup (geom->lg_name); + grub_disk_addr_t off = 0; + struct gconfig *config; + grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); + + grub_util_follow_gpart_up (name_tmp, &off, name_out); + free (name_tmp); + LIST_FOREACH (config, &provider->lg_config, lg_config) + if (strcasecmp (config->lg_name, "start") == 0) + off += strtoull (config->lg_val, 0, 10); + if (off_out) + *off_out = off; + return; + } + } + grub_util_info ("geom '%s' has no parent", name); + if (name_out) + *name_out = xstrdup (name); + if (off_out) + *off_out = 0; +} + static grub_disk_addr_t find_partition_start (const char *dev) { diff --git a/util/getroot.c b/util/getroot.c index 8fce283bc..41fbdec10 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -790,56 +790,6 @@ grub_util_get_dm_abstraction (const char *os_dev) #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include -/* FIXME: geom actually gives us the whole container hierarchy. - It can be used more efficiently than this. */ -void -grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) -{ - struct gmesh mesh; - struct gclass *class; - int error; - struct ggeom *geom; - - grub_util_info ("following geom '%s'", name); - - error = geom_gettree (&mesh); - if (error != 0) - grub_util_error ("couldn't open geom"); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - if (strcasecmp (class->lg_name, "part") == 0) - break; - if (!class) - grub_util_error ("couldn't open geom part"); - - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - char *name_tmp = xstrdup (geom->lg_name); - grub_disk_addr_t off = 0; - struct gconfig *config; - grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); - - grub_util_follow_gpart_up (name_tmp, &off, name_out); - free (name_tmp); - LIST_FOREACH (config, &provider->lg_config, lg_config) - if (strcasecmp (config->lg_name, "start") == 0) - off += strtoull (config->lg_val, 0, 10); - if (off_out) - *off_out = off; - return; - } - } - grub_util_info ("geom '%s' has no parent", name); - if (name_out) - *name_out = xstrdup (name); - if (off_out) - *off_out = 0; -} - static const char * grub_util_get_geom_abstraction (const char *dev) { From 3ae17eb83c25cd9b82a8e49a3235168661d8cdbe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:44:18 +0100 Subject: [PATCH 172/315] Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. * grub-core/fs/zfs/zfscrypt.c (grub_zfs_decrypt_real): Use explicit byteswap when needed. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfscrypt.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 925b798bc..b23f5156d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-08 Vladimir Serbinenko + + Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. + + * grub-core/fs/zfs/zfscrypt.c (grub_zfs_decrypt_real): Use explicit + byteswap when needed. + 2011-11-08 Vladimir Serbinenko Fix FreeBSD compilation. diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 14babd29f..13f62b25a 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -277,8 +277,9 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, grub_err_t err; grub_memcpy (sw, nonce, 16); - for (i = 0; i < 4; i++) - sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + if (endian != GRUB_ZFS_BIG_ENDIAN) + for (i = 0; i < 4; i++) + sw[i] = grub_swap_bytes32 (sw[i]); if (!cipher) return grub_error (GRUB_ERR_ACCESS_DENIED, From 49a45021c1430b481ef4c0be95912e065aa9402f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:46:41 +0100 Subject: [PATCH 173/315] * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not used variable. * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): Likewise. --- ChangeLog | 7 +++++++ grub-core/kern/ia64/dl_helper.c | 3 --- grub-core/lib/LzmaEnc.c | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b23f5156d..b7bd30183 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not + used variable. + * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): + Likewise. + 2011-11-08 Vladimir Serbinenko Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c index 91f28026e..958cdb25e 100644 --- a/grub-core/kern/ia64/dl_helper.c +++ b/grub-core/kern/ia64/dl_helper.c @@ -30,7 +30,6 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, const Elf64_Ehdr *e = ehdr; grub_size_t cntt = 0, cntg = 0;; const Elf64_Shdr *s; - Elf64_Word entsize; unsigned i; /* Find a symbol table. */ @@ -43,8 +42,6 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, if (i == grub_le_to_cpu16 (e->e_shnum)) return; - entsize = s->sh_entsize; - for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff)); i < grub_le_to_cpu16 (e->e_shnum); i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c index 01ffa91f9..258ed9c91 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/grub-core/lib/LzmaEnc.c @@ -1994,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; From 438a746a3ff63ed0428818a4f03b181431199747 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 20:03:06 +0100 Subject: [PATCH 174/315] * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed with no error set. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b7bd30183..f8f424176 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed + with no error set. + 2011-11-08 Vladimir Serbinenko * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index fb16a009b..f85d56e99 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1324,7 +1324,7 @@ read_dva (const dva_t *dva, { grub_uint64_t offset; unsigned i; - grub_err_t err; + grub_err_t err = 0; int try = 0; offset = dva_get_offset (dva, endian); @@ -1344,6 +1344,9 @@ read_dva (const dva_t *dva, if (err) return err; } + if (!err) + return grub_error (GRUB_ERR_BAD_FS, "unknown device %d", + (int) DVA_GET_VDEV (dva)); return err; } From 52b656c037a679c74e9c49dd2c92f289a18b2d4c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 11:43:39 +0100 Subject: [PATCH 175/315] Several AFFS fixes. * grub-core/fs/affs.c (grub_affs_bblock): Replace flags with version. (GRUB_AFFS_FLAG_FFS): Removed. (GRUB_AFFS_SYMLINK_SIZE): Likewise. (GRUB_AFFS_FILETYPE_DIR): Make positive and unsigned. (GRUB_AFFS_FILETYPE_DIR), (GRUB_AFFS_FILETYPE_REG): Fix a mix-up. (grub_fshelp_node): Make block 32-bit. Add block_cache and last_block_cache. (grub_affs_read_block): Fill and use block cache. (grub_affs_read_file): Removed. (grub_affs_mount): Zero-fill node. Fix version check. Don't reread boot block. (grub_affs_read_symlink): Fix symlink size. Add a \0 at the end for safety. (grub_affs_iterate_dir): Use more appropriate types. Zero-fill allocated space. (grub_affs_close): Free block cache. (grub_affs_read): Use grub_fshelp_read_file directly. --- ChangeLog | 22 +++++++++ grub-core/fs/affs.c | 111 +++++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8f424176..035f18194 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2011-11-09 Vladimir Serbinenko + + Several AFFS fixes. + + * grub-core/fs/affs.c (grub_affs_bblock): Replace flags with version. + (GRUB_AFFS_FLAG_FFS): Removed. + (GRUB_AFFS_SYMLINK_SIZE): Likewise. + (GRUB_AFFS_FILETYPE_DIR): Make positive and unsigned. + (GRUB_AFFS_FILETYPE_DIR), (GRUB_AFFS_FILETYPE_REG): Fix a mix-up. + (grub_fshelp_node): Make block 32-bit. + Add block_cache and last_block_cache. + (grub_affs_read_block): Fill and use block cache. + (grub_affs_read_file): Removed. + (grub_affs_mount): Zero-fill node. Fix version check. Don't reread + boot block. + (grub_affs_read_symlink): Fix symlink size. Add a \0 at the end for + safety. + (grub_affs_iterate_dir): Use more appropriate types. Zero-fill allocated + space. + (grub_affs_close): Free block cache. + (grub_affs_read): Use grub_fshelp_read_file directly. + 2011-11-08 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index adf2932bd..06f41c4c3 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -32,15 +32,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_affs_bblock { grub_uint8_t type[3]; - grub_uint8_t flags; + grub_uint8_t version; grub_uint32_t checksum; grub_uint32_t rootblock; } __attribute__ ((packed)); -/* Set if the filesystem is a AFFS filesystem. Otherwise this is an - OFS filesystem. */ -#define GRUB_AFFS_FLAG_FFS 1 - /* The affs rootblock. */ struct grub_affs_rblock { @@ -85,19 +81,19 @@ struct grub_affs_file #define GRUB_AFFS_BLOCKPTR_OFFSET 24 #define GRUB_AFFS_SYMLINK_OFFSET 24 -#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225) - -#define GRUB_AFFS_FILETYPE_DIR -3 -#define GRUB_AFFS_FILETYPE_REG 2 +#define GRUB_AFFS_FILETYPE_REG 0xfffffffd +#define GRUB_AFFS_FILETYPE_DIR 2 #define GRUB_AFFS_FILETYPE_SYMLINK 3 struct grub_fshelp_node { struct grub_affs_data *data; - grub_disk_addr_t block; + grub_uint32_t block; struct grub_fshelp_node *parent; struct grub_affs_file di; + grub_uint32_t *block_cache; + grub_uint32_t last_block_cache; }; /* Information about a "mounted" affs filesystem. */ @@ -120,32 +116,46 @@ static grub_dl_t my_mod; static grub_disk_addr_t grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { - int links; + grub_uint32_t target, curblock; grub_uint32_t pos; - int block = node->block; struct grub_affs_file file; struct grub_affs_data *data = node->data; grub_uint64_t mod; + if (!node->block_cache) + { + node->block_cache = grub_malloc ((((grub_be_to_cpu32 (node->di.size) + + 511) >> 9) / data->htsize + 1) + * sizeof (node->block_cache[0])); + if (!node->block_cache) + return -1; + node->last_block_cache = 0; + node->block_cache[0] = node->block; + } + + /* Files are at most 2G on AFFS, so no need for 64-bit division. */ + target = (grub_uint32_t) fileblock / data->htsize; + mod = (grub_uint32_t) fileblock % data->htsize; /* Find the block that points to the fileblock we are looking up by following the chain until the right table is reached. */ - for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--) + for (curblock = node->last_block_cache + 1; curblock <= target; curblock++) { - grub_disk_read (data->disk, block + data->blocksize - 1, + grub_disk_read (data->disk, + node->block_cache[curblock - 1] + data->blocksize - 1, data->blocksize * (GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION), sizeof (file), &file); if (grub_errno) return 0; - block = grub_be_to_cpu32 (file.extension); + node->block_cache[curblock] = grub_be_to_cpu32 (file.extension); + node->last_block_cache = curblock; } /* Translate the fileblock to the block within the right table. */ - fileblock = mod; - grub_disk_read (data->disk, block, + grub_disk_read (data->disk, node->block_cache[target], GRUB_AFFS_BLOCKPTR_OFFSET - + (data->htsize - fileblock - 1) * sizeof (pos), + + (data->htsize - mod - 1) * sizeof (pos), sizeof (pos), &pos); if (grub_errno) return 0; @@ -153,21 +163,6 @@ grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) return grub_be_to_cpu32 (pos); } - -/* Read LEN bytes from the file described by DATA starting with byte - POS. Return the amount of read bytes in READ. */ -static grub_ssize_t -grub_affs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_affs_read_block, - grub_be_to_cpu32 (node->di.size), 0); -} - - static struct grub_affs_data * grub_affs_mount (grub_disk_t disk) { @@ -178,7 +173,7 @@ grub_affs_mount (grub_disk_t disk) int checksum = 0; int blocksize = 0; - data = grub_malloc (sizeof (struct grub_affs_data)); + data = grub_zalloc (sizeof (struct grub_affs_data)); if (!data) return 0; @@ -196,18 +191,12 @@ grub_affs_mount (grub_disk_t disk) } /* Test if the filesystem is a OFS filesystem. */ - if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS)) + if (data->bblock.version < 1) { grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported"); goto fail; } - /* Read the bootblock. */ - grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock), - &data->bblock); - if (grub_errno) - goto fail; - /* No sane person uses more than 8KB for a block. At least I hope for that person because in that case this won't work. */ rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16); @@ -270,18 +259,21 @@ grub_affs_read_symlink (grub_fshelp_node_t node) { struct grub_affs_data *data = node->data; char *symlink; + const grub_size_t symlink_size = (data->blocksize * GRUB_DISK_SECTOR_SIZE + - 225); - symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize)); + symlink = grub_malloc (symlink_size + 1); if (!symlink) return 0; grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET, - GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink); + symlink_size, symlink); if (grub_errno) { grub_free (symlink); return 0; } + symlink[symlink_size] = 1; grub_dprintf ("affs", "Symlink: `%s'\n", symlink); return symlink; } @@ -301,24 +293,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, grub_uint32_t *hashtable; auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_disk_addr_t block, + grub_uint32_t block, const struct grub_affs_file *fil); int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_disk_addr_t block, + grub_uint32_t block, const struct grub_affs_file *fil) { int type; - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) { grub_free (hashtable); return 1; } - if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR) + if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG) type = GRUB_FSHELP_REG; - else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG) + else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR) type = GRUB_FSHELP_DIR; else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK) type = GRUB_FSHELP_SYMLINK; @@ -339,7 +331,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, } /* Create the directory entries for `.' and `..'. */ - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) return 1; @@ -348,7 +340,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; if (dir->parent) { - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) return 1; *node = *dir->parent; @@ -356,7 +348,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; } - hashtable = grub_malloc (data->htsize * sizeof (*hashtable)); + hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); if (!hashtable) return 1; @@ -367,7 +359,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, for (i = 0; i < data->htsize; i++) { - grub_uint64_t next; + grub_uint32_t next; if (!hashtable[i]) continue; @@ -441,10 +433,13 @@ grub_affs_open (struct grub_file *file, const char *name) return grub_errno; } - static grub_err_t grub_affs_close (grub_file_t file) { + struct grub_affs_data *data = + (struct grub_affs_data *) file->data; + + grub_free (data->diropen.block_cache); grub_free (file->data); grub_dl_unref (my_mod); @@ -452,7 +447,6 @@ grub_affs_close (grub_file_t file) return GRUB_ERR_NONE; } - /* Read LEN bytes data from FILE into BUF. */ static grub_ssize_t grub_affs_read (grub_file_t file, char *buf, grub_size_t len) @@ -460,13 +454,12 @@ grub_affs_read (grub_file_t file, char *buf, grub_size_t len) struct grub_affs_data *data = (struct grub_affs_data *) file->data; - int size = grub_affs_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); - - return size; + return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen, + file->read_hook, + file->offset, len, buf, grub_affs_read_block, + grub_be_to_cpu32 (data->diropen.di.size), 0); } - static grub_err_t grub_affs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, From 19e81ba7a0b67bb1bd3d427c9c7cc1147a78ec8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 14:44:21 +0100 Subject: [PATCH 176/315] * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. --- ChangeLog | 4 ++++ configure.ac | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 035f18194..1b7fd4411 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-09 Vladimir Serbinenko + + * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. + 2011-11-09 Vladimir Serbinenko Several AFFS fixes. diff --git a/configure.ac b/configure.ac index e707081a7..1b3288c8a 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,7 @@ if test "x$target_m32" = x1; then # Force 32-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m32" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" TARGET_MODULE_FORMAT="elf32" fi @@ -472,6 +473,7 @@ if test "x$target_m64" = x1; then # Force 64-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m64" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" TARGET_MODULE_FORMAT="elf64" fi From 57b01250046a33900d3e4b7434967aacb343bc7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 14:47:45 +0100 Subject: [PATCH 177/315] * include/grub/misc.h (grub_strncat): Fix the order of conditionals to avoid accessing beyond the array. --- ChangeLog | 5 +++++ include/grub/misc.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1b7fd4411..352c69c4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-09 Vladimir Serbinenko + + * include/grub/misc.h (grub_strncat): Fix the order of conditionals to + avoid accessing beyond the array. + 2011-11-09 Vladimir Serbinenko * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. diff --git a/include/grub/misc.h b/include/grub/misc.h index 5bc159e7d..4e7d9077c 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -87,7 +87,7 @@ grub_strncat (char *dest, const char *src, int c) while (*p) p++; - while ((*p = *src) != '\0' && c--) + while (c-- && (*p = *src) != '\0') { p++; src++; From 8a5a3a5b5a3f53520f8dd63808e5715558d0d326 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 15:01:58 +0100 Subject: [PATCH 178/315] Fix several memory leaks. * grub-core/fs/btrfs.c (grub_btrfs_dir): Fix memory leak. * grub-core/fs/cpio.c (grub_cpio_find_file): Likewise. (grub_cpio_dir): Likewise. * grub-core/fs/fat.c (grub_fat_label): Likewise. * grub-core/fs/jfs.c (grub_jfs_label): Likewise. * grub-core/fs/romfs.c (grub_romfs_close): Likewise. (grub_romfs_label): Likewise. * grub-core/fs/squash4.c (squash_mount): Use zalloc for safety. (squash_unmount): New function. (grub_squash_dir): Fix memory leak. (grub_squash_open): Likewise. (grub_squash_read): Likewise. (grub_squash_mtime): Likewise. * grub-core/fs/xfs.c (grub_xfs_open): Likewise. * grub-core/fs/zfs/zfs.c (check_pool_label): Likewise. * util/grub-fstest.c (fstest): Likewise. --- ChangeLog | 21 +++++++++++++++++++++ grub-core/fs/btrfs.c | 29 +++++++++++++++++++---------- grub-core/fs/cpio.c | 3 +++ grub-core/fs/fat.c | 6 +++++- grub-core/fs/jfs.c | 2 ++ grub-core/fs/romfs.c | 6 +++++- grub-core/fs/squash4.c | 22 +++++++++++++++++----- grub-core/fs/xfs.c | 11 +++++++---- grub-core/fs/zfs/zfs.c | 2 ++ util/grub-fstest.c | 4 +++- 10 files changed, 84 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 352c69c4f..c367bb134 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2011-11-09 Vladimir Serbinenko + + Fix several memory leaks. + + * grub-core/fs/btrfs.c (grub_btrfs_dir): Fix memory leak. + * grub-core/fs/cpio.c (grub_cpio_find_file): Likewise. + (grub_cpio_dir): Likewise. + * grub-core/fs/fat.c (grub_fat_label): Likewise. + * grub-core/fs/jfs.c (grub_jfs_label): Likewise. + * grub-core/fs/romfs.c (grub_romfs_close): Likewise. + (grub_romfs_label): Likewise. + * grub-core/fs/squash4.c (squash_mount): Use zalloc for safety. + (squash_unmount): New function. + (grub_squash_dir): Fix memory leak. + (grub_squash_open): Likewise. + (grub_squash_read): Likewise. + (grub_squash_mtime): Likewise. + * grub-core/fs/xfs.c (grub_xfs_open): Likewise. + * grub-core/fs/zfs/zfs.c (check_pool_label): Likewise. + * util/grub-fstest.c (fstest): Likewise. + 2011-11-09 Vladimir Serbinenko * include/grub/misc.h (grub_strncat): Fix the order of conditionals to diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 3dc680034..e5aa3084c 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1415,22 +1415,28 @@ grub_btrfs_dir (grub_device_t device, const char *path, err = find_path (data, path, &key_in, &tree, &type); if (err) - return err; + { + grub_btrfs_unmount (data); + return err; + } if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + { + grub_btrfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc); if (err) - return err; + { + grub_btrfs_unmount (data); + return err; + } if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM || key_out.object_id != key_in.object_id) { r = next (data, &desc, &elemaddr, &elemsize, &key_out); if (r <= 0) - { - free_iterator (&desc); - return -r; - } + goto out; } do { @@ -1448,14 +1454,17 @@ grub_btrfs_dir (grub_device_t device, const char *path, direl = grub_malloc (allocated + 1); if (!direl) { - free_iterator (&desc); - return grub_errno; + r = -grub_errno; + break; } } err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize); if (err) - return err; + { + r = -err; + break; + } for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index b43e54ec9..39b35b335 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -147,6 +147,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, && grub_memcmp(*name, "TRAILER!!!", 11) == 0) { *ofs = 0; + grub_free (*name); return GRUB_ERR_NONE; } @@ -481,6 +482,8 @@ grub_cpio_dir (grub_device_t device, const char *path_in, } } } + else + grub_free (name); data->hofs = ofs; } diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index fb1113814..0d32e229d 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -1048,7 +1048,10 @@ grub_fat_label (grub_device_t device, char **label) grub_size_t chc; *label = grub_malloc (11 * 4 + 1); if (!*label) - return grub_errno; + { + grub_free (data); + return grub_errno; + } chc = dir.type_specific.volume_label.character_count; if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) chc = ARRAY_SIZE (dir.type_specific.volume_label.str); @@ -1057,6 +1060,7 @@ grub_fat_label (grub_device_t device, char **label) } } + grub_free (data); return grub_errno; } diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index cf7520bb3..91497f143 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -891,6 +891,8 @@ grub_jfs_label (grub_device_t device, char **label) else *label = 0; + grub_free (data); + return grub_errno; } diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 713e8293f..202ca102e 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -397,7 +397,10 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_romfs_close (grub_file_t file) { - grub_free (file->data); + struct grub_fshelp_node *data = file->data; + + grub_free (data->data); + grub_free (data); return GRUB_ERR_NONE; } @@ -432,6 +435,7 @@ grub_romfs_label (grub_device_t device, char **label) return err; } (*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0; + grub_free (data); return GRUB_ERR_NONE; } diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index a3832b6be..0728287b7 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -287,7 +287,7 @@ squash_mount (grub_disk_t disk) if (err) return NULL; - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data)); if (!data) return NULL; data->sb = sb; @@ -418,6 +418,15 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) grub_cpu_to_le16 (data->sb.root_ino_offset)); } +static void +squash_unmount (struct grub_squash_data *data) +{ + grub_free (data->ino.cumulated_block_sizes); + grub_free (data->ino.block_sizes); + grub_free (data); +} + + static grub_err_t grub_squash_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, @@ -436,6 +445,7 @@ grub_squash_dir (grub_device_t device, const char *path, info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.mtimeset = 1; info.mtime = grub_le_to_cpu32 (node->ino.mtime); + grub_free (node); return hook (filename, &info); } @@ -457,7 +467,7 @@ grub_squash_dir (grub_device_t device, const char *path, if (!grub_errno) grub_squash_iterate_dir (fdiro, iterate); - grub_free (data); + squash_unmount (data); return grub_errno; } @@ -482,7 +492,7 @@ grub_squash_open (struct grub_file *file, const char *name) grub_squash_read_symlink, GRUB_FSHELP_REG); if (grub_errno) { - grub_free (data); + squash_unmount (data); return grub_errno; } @@ -499,6 +509,8 @@ grub_squash_open (struct grub_file *file, const char *name) else file->size = grub_le_to_cpu32 (fdiro->ino.file.size); + grub_free (fdiro); + return GRUB_ERR_NONE; } @@ -664,7 +676,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_squash_close (grub_file_t file) { - grub_free (file->data); + squash_unmount (file->data); return GRUB_ERR_NONE; } @@ -677,7 +689,7 @@ grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) if (! data) return grub_errno; *tm = grub_le_to_cpu32 (data->sb.creation_time); - grub_free (data); + squash_unmount (data); return GRUB_ERR_NONE; } diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 3dc5e0af0..c4d47a099 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -771,10 +771,13 @@ grub_xfs_open (struct grub_file *file, const char *name) } if (fdiro != &data->diropen) - grub_memcpy (&data->diropen, fdiro, - sizeof (struct grub_fshelp_node) - - sizeof (struct grub_xfs_inode) - + (1 << data->sblock.log2_inode)); + { + grub_memcpy (&data->diropen, fdiro, + sizeof (struct grub_fshelp_node) + - sizeof (struct grub_xfs_inode) + + (1 << data->sblock.log2_inode)); + grub_free (fdiro); + } file->size = grub_be_to_cpu64 (data->diropen.inode.size); file->data = data; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index f85d56e99..7ceb16db2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -781,9 +781,11 @@ check_pool_label (struct grub_zfs_data *data, err = fill_vdev_info (data, nv, diskdesc); if (err) { + grub_free (nv); grub_free (nvlist); return err; } + grub_free (nv); } grub_dprintf ("zfs", "check 10 passed\n"); diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f90755e86..47b536771 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -401,7 +401,9 @@ fstest (int n, char **args) if (!uuid) grub_util_error ("couldn't retrieve UUID"); argv[1] = uuid; - execute_command ("xnu_uuid", 2, argv); + execute_command ("xnu_uuid", 2, argv); + grub_free (uuid); + grub_device_close (dev); } } From 28840fdaae146999e51d5741a6434b4f3ffaf54c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:07:51 +0100 Subject: [PATCH 179/315] * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): Fix declaration. --- ChangeLog | 5 +++++ include/grub/i386/netbsd_bootinfo.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c367bb134..7cd370c1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): + Fix declaration. + 2011-11-09 Vladimir Serbinenko Fix several memory leaks. diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h index 228f26aaa..24e145b01 100644 --- a/include/grub/i386/netbsd_bootinfo.h +++ b/include/grub/i386/netbsd_bootinfo.h @@ -92,7 +92,7 @@ struct grub_netbsd_btinfo_bootwedge { grub_disk_addr_t matchblk; grub_uint64_t matchnblks; grub_uint8_t matchhash[16]; /* MD5 hash */ -} __packed; +} __attribute__ ((packed)); struct grub_netbsd_btinfo_symtab { From 6b68db81fc42ed6a4b9aa7f15f5578136c383980 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:09:33 +0100 Subject: [PATCH 180/315] * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for >= 6 drives. --- ChangeLog | 5 +++++ grub-core/fs/btrfs.c | 9 ++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cd370c1b..506036d5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for + >= 6 drives. + 2011-11-10 Vladimir Serbinenko * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index e5aa3084c..fae9199a4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -734,12 +734,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, &low); high = grub_divmod64 (middle, - grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu16 (chunk->nstripes) + / grub_le_to_cpu16 (chunk->nsubstripes), &stripen); - stripen *= grub_le_to_cpu16 (chunk->nstripes) - / grub_le_to_cpu16 (chunk->nsubstripes); - redundancy = grub_le_to_cpu16 (chunk->nstripes) - / grub_le_to_cpu16 (chunk->nsubstripes); + stripen *= grub_le_to_cpu16 (chunk->nsubstripes); + redundancy = grub_le_to_cpu16 (chunk->nsubstripes); stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) * high; csize = grub_le_to_cpu64 (chunk->stripe_length) - low; From ad9a2f44b4cbf8e22a65f9f019b7914f1a60d169 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:16:27 +0100 Subject: [PATCH 181/315] * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat argument (access out of bounds). --- ChangeLog | 5 +++++ grub-core/fs/iso9660.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 506036d5a..ef82df3af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat + argument (access out of bounds). + 2011-11-10 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index d4c52bed4..5e2f7824a 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -559,9 +559,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename = ".."; else if (entry->len >= 5) { - int size = 1; + grub_size_t size = 1, csize = 1; char *old; - size = entry->len - 5; + csize = size = entry->len - 5; old = filename; if (filename_alloc) { @@ -580,7 +580,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, return grub_errno; } filename_alloc = 1; - grub_strncat (filename, (char *) &entry->data[1], size); + grub_strncat (filename, (char *) &entry->data[1], csize); filename[size] = '\0'; } } From 45bd824d2eed877eef2c55c96063eefbc4a3c5d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:38:06 +0100 Subject: [PATCH 182/315] Fix ZFS memory and resource leaks. * grub-core/fs/zfs/zfs.c (fill_vdev_info_real): New paramter inserted. All users updated. Free type on exit. (fill_vdev_info): New parameter inserted. All users updated. (check_pool_label): Likewise. (scan_disk): Likewise. (scan_devices): Close non-inserted disks. (fzap_iterate): Free l. (unmount_device): Free children descripto memory. --- ChangeLog | 14 +++++++ grub-core/fs/zfs/zfs.c | 84 +++++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef82df3af..24a2b783b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-10 Vladimir Serbinenko + + Fix ZFS memory and resource leaks. + + * grub-core/fs/zfs/zfs.c (fill_vdev_info_real): New paramter inserted. + All users updated. + Free type on exit. + (fill_vdev_info): New parameter inserted. All users updated. + (check_pool_label): Likewise. + (scan_disk): Likewise. + (scan_devices): Close non-inserted disks. + (fzap_iterate): Free l. + (unmount_device): Free children descripto memory. + 2011-11-10 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 7ceb16db2..760668940 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -535,7 +535,8 @@ static grub_err_t fill_vdev_info_real (struct grub_zfs_data *data, const char *nvlist, struct grub_zfs_device_desc *fill, - struct grub_zfs_device_desc *insert) + struct grub_zfs_device_desc *insert, + int *inserted) { char *type; @@ -545,10 +546,16 @@ fill_vdev_info_real (struct grub_zfs_data *data, return grub_errno; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id))) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + } if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + } if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 || grub_strcmp (type, VDEV_TYPE_FILE) == 0) @@ -563,8 +570,11 @@ fill_vdev_info_real (struct grub_zfs_data *data, fill->original = insert->original; if (!data->device_original) data->device_original = fill; + *inserted = 1; } + grub_free (type); + return GRUB_ERR_NONE; } @@ -580,17 +590,27 @@ fill_vdev_info_real (struct grub_zfs_data *data, grub_uint64_t par; fill->type = DEVICE_RAIDZ; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + } fill->nparity = par; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + } fill->ashift = par; } - nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, + ZPOOL_CONFIG_CHILDREN); if (nelm <= 0) - return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + } if (!fill->children) { @@ -608,34 +628,43 @@ fill_vdev_info_real (struct grub_zfs_data *data, child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); - err = fill_vdev_info_real (data, child, &fill->children[i], insert); + err = fill_vdev_info_real (data, child, &fill->children[i], insert, + inserted); grub_free (child); if (err) - return err; + { + grub_free (type); + return err; + } } + grub_free (type); return GRUB_ERR_NONE; } - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", - type); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type); + grub_free (type); + return grub_errno; } static grub_err_t fill_vdev_info (struct grub_zfs_data *data, - char *nvlist, struct grub_zfs_device_desc *diskdesc) + char *nvlist, struct grub_zfs_device_desc *diskdesc, + int *inserted) { grub_uint64_t id; unsigned i; + *inserted = 0; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id)) return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == id) return fill_vdev_info_real (data, nvlist, &data->devices_attached[i], - diskdesc); + diskdesc, inserted); data->n_devices_attached++; if (data->n_devices_attached > data->n_devices_allocated) @@ -658,7 +687,7 @@ fill_vdev_info (struct grub_zfs_data *data, return fill_vdev_info_real (data, nvlist, &data->devices_attached[data->n_devices_attached - 1], - diskdesc); + diskdesc, inserted); } /* @@ -667,7 +696,8 @@ fill_vdev_info (struct grub_zfs_data *data, */ static grub_err_t check_pool_label (struct grub_zfs_data *data, - struct grub_zfs_device_desc *diskdesc) + struct grub_zfs_device_desc *diskdesc, + int *inserted) { grub_uint64_t pool_state, txg = 0; char *nvlist; @@ -679,6 +709,8 @@ check_pool_label (struct grub_zfs_data *data, int found; grub_err_t err; + *inserted = 0; + err = zfs_fetch_nvlist (diskdesc, &nvlist); if (err) return err; @@ -778,7 +810,7 @@ check_pool_label (struct grub_zfs_data *data, grub_free (nvlist); return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); } - err = fill_vdev_info (data, nv, diskdesc); + err = fill_vdev_info (data, nv, diskdesc, inserted); if (err) { grub_free (nv); @@ -796,7 +828,7 @@ check_pool_label (struct grub_zfs_data *data, static grub_err_t scan_disk (grub_device_t dev, struct grub_zfs_data *data, - int original) + int original, int *inserted) { int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; @@ -858,7 +890,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, grub_memmove (&(data->current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); - err = check_pool_label (data, &desc); + err = check_pool_label (data, &desc, inserted); if (err) { grub_errno = GRUB_ERR_NONE; @@ -889,6 +921,7 @@ scan_devices (struct grub_zfs_data *data) { grub_device_t dev; grub_err_t err; + int inserted; dev = grub_device_open (name); if (!dev) return 0; @@ -897,7 +930,7 @@ scan_devices (struct grub_zfs_data *data) grub_device_close (dev); return 0; } - err = scan_disk (dev, data, 0); + err = scan_disk (dev, data, 0, &inserted); if (err == GRUB_ERR_BAD_FS) { grub_device_close (dev); @@ -910,6 +943,9 @@ scan_devices (struct grub_zfs_data *data) grub_print_error (); return 0; } + + if (!inserted) + grub_device_close (dev); return 0; } @@ -2042,10 +2078,14 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, if (hook (buf, le->le_name_length, val, le->le_value_length, le->le_int_size)) - return 1; + { + grub_free (l); + return 1; + } grub_free (buf); grub_free (val); } + grub_free (l); } return 0; } @@ -3156,6 +3196,7 @@ unmount_device (struct grub_zfs_device_desc *desc) case DEVICE_MIRROR: for (i = 0; i < desc->n_children; i++) unmount_device (&desc->children[i]); + grub_free (desc->children); return; } } @@ -3190,6 +3231,7 @@ zfs_mount (grub_device_t dev) grub_size_t ospsize; grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; + int inserted; if (! dev->disk) { @@ -3210,7 +3252,7 @@ zfs_mount (grub_device_t dev) data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) * data->n_devices_allocated); data->n_devices_attached = 0; - err = scan_disk (dev, data, 1); + err = scan_disk (dev, data, 1, &inserted); if (err) { zfs_unmount (data); From cb544caa2ecd10367cd05d5ebbcdc019fdab255a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:43:08 +0100 Subject: [PATCH 183/315] * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. --- ChangeLog | 4 ++++ grub-core/fs/zfs/zfs.c | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24a2b783b..2687b65be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. + 2011-11-10 Vladimir Serbinenko Fix ZFS memory and resource leaks. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 760668940..20cba3509 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -3227,7 +3227,7 @@ zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; grub_err_t err; - objset_phys_t *osp = 0; + void *osp = 0; grub_size_t ospsize; grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; @@ -3265,7 +3265,7 @@ zfs_mount (grub_device_t dev) ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); err = zio_read (&ub->ub_rootbp, ub_endian, - (void **) &osp, &ospsize, data); + &osp, &ospsize, data); if (err) { zfs_unmount (data); @@ -3281,7 +3281,8 @@ zfs_mount (grub_device_t dev) } /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode, + DNODE_SIZE); data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop, ub_endian) >> 63) & 1; grub_free (osp); From c3591189b82421a8eaeebc97c118d81bba1931cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:46:09 +0100 Subject: [PATCH 184/315] Remove local keyword. * util/grub-mkconfig_lib.in (version_test_numeric): Remove local. (version_test_gt): Likewise. (version_find_latest): Likewise. (gettext_printf): Likewise. * util/grub.d/10_windows.in (get_os_name_from_boot_ini): Likewise. --- ChangeLog | 10 ++++++++ util/grub-mkconfig_lib.in | 48 +++++++++++++++++++-------------------- util/grub.d/10_windows.in | 10 ++++---- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2687b65be..e60b4da9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-10 Vladimir Serbinenko + + Remove local keyword. + + * util/grub-mkconfig_lib.in (version_test_numeric): Remove local. + (version_test_gt): Likewise. + (version_find_latest): Likewise. + (gettext_printf): Likewise. + * util/grub.d/10_windows.in (get_os_name_from_boot_ini): Likewise. + 2011-11-10 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index a453a6bb5..5a9bf90c0 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -167,21 +167,21 @@ grub_file_is_not_garbage () version_test_numeric () { - local a="$1" - local cmp="$2" - local b="$3" - if [ "$a" = "$b" ] ; then - case "$cmp" in + version_test_numeric_a="$1" + version_test_numeric_cmp="$2" + version_test_numeric_b="$3" + if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then + case "$version_test_numeric_cmp" in ge|eq|le) return 0 ;; gt|lt) return 1 ;; esac fi - if [ "$cmp" = "lt" ] ; then - c="$a" - a="$b" - b="$c" + if [ "$version_test_numeric_cmp" = "lt" ] ; then + version_test_numeric_c="$version_test_numeric_a" + version_test_numeric_a="$version_test_numeric_b" + version_test_numeric_b="$version_test_numeric_c" fi - if (echo "$a" ; echo "$b") | sort -n | head -n 1 | grep -qx "$b" ; then + if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | sort -n | head -n 1 | grep -qx "$version_test_numeric_b" ; then return 0 else return 1 @@ -190,30 +190,30 @@ version_test_numeric () version_test_gt () { - local a="`echo "$1" | sed -e "s/[^-]*-//"`" - local b="`echo "$2" | sed -e "s/[^-]*-//"`" - local cmp=gt - if [ "x$b" = "x" ] ; then + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" + version_test_gt_cmp=gt + if [ "x$version_test_gt_b" = "x" ] ; then return 0 fi - case "$a:$b" in + case "$version_test_gt_a:$version_test_gt_b" in *.old:*.old) ;; - *.old:*) a="`echo -n "$a" | sed -e 's/\.old$//'`" ; cmp=gt ;; - *:*.old) b="`echo -n "$b" | sed -e 's/\.old$//'`" ; cmp=ge ;; + *.old:*) version_test_gt_a="`echo -n "$version_test_gt_a" | sed -e 's/\.old$//'`" ; cmp=gt ;; + *:*.old) version_test_gt_b="`echo -n "$version_test_gt_b" | sed -e 's/\.old$//'`" ; cmp=ge ;; esac - version_test_numeric "$a" "$cmp" "$b" + version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" return "$?" } version_find_latest () { - local a="" + version_find_latest_a="" for i in "$@" ; do - if version_test_gt "$i" "$a" ; then - a="$i" + if version_test_gt "$i" "$version_find_latest_a" ; then + version_find_latest_a="$i" fi done - echo "$a" + echo "$version_find_latest_a" } # One layer of quotation is eaten by "", the second by sed, and the third by @@ -227,9 +227,9 @@ gettext_quoted () { # remaining arguments to printf. This is a useful abbreviation and tends to # be easier to type. gettext_printf () { - local format="$1" + gettext_printf_format="$1" shift - printf "$(gettext_quoted "$format")" "$@" + printf "$(gettext_quoted "$gettext_printf_format")" "$@" } uses_abstraction () { diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 0a848880d..20fd4e044 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -42,14 +42,14 @@ get_os_name_from_boot_ini () sort | uniq | wc -l`" = 1 || return 1 # Search 'default=PARTITION' - local part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` - test -n "$part" || return 1 + get_os_name_from_boot_ini_part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` + test -n "$get_os_name_from_boot_ini_part" || return 1 # Search 'PARTITION="NAME" ...' - local name=`sed -n 's,\\\\,/,g;s,^'"$part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q` - test -n "$name" || return 1 + get_os_name_from_boot_ini_name=`sed -n 's,\\\\,/,g;s,^'"$get_os_name_from_boot_ini_part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q` + test -n "$get_os_name_from_boot_ini_name" || return 1 - echo "$name" + echo "$get_os_name_from_boot_ini_name" } From f627652531ee17d729e024858d529c9b05657593 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 09:31:06 +0100 Subject: [PATCH 185/315] Put symlink at the end of the node and fix a potential memory corruption. * grub-core/fs/iso9660.c (grub_fshelp_node): New field have_symlink. Make symlink into an array. (set_rockridge): Set have_symlink and alloc_dirents. (grub_iso9660_read_symlink): Use new layout. (grub_iso9660_iterate_dir): Fix memory corruption. Use new layout. (grub_iso9660_dir): Set have_symlink. (grub_iso9660_open): Likewise. --- ChangeLog | 14 +++++++++++ grub-core/fs/iso9660.c | 55 +++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index e60b4da9c..f293e0773 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-10 Vladimir Serbinenko + + Put symlink at the end of the node and fix a potential + memory corruption. + + * grub-core/fs/iso9660.c (grub_fshelp_node): New field have_symlink. + Make symlink into an array. + (set_rockridge): Set have_symlink and alloc_dirents. + (grub_iso9660_read_symlink): Use new layout. + (grub_iso9660_iterate_dir): Fix memory corruption. + Use new layout. + (grub_iso9660_dir): Set have_symlink. + (grub_iso9660_open): Likewise. + 2011-11-10 Vladimir Serbinenko Remove local keyword. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 5e2f7824a..7b1e32f7c 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -159,8 +159,9 @@ struct grub_fshelp_node { struct grub_iso9660_data *data; grub_size_t have_dirents, alloc_dirents; - char *symlink; + int have_symlink; struct grub_iso9660_dir dirents[8]; + char symlink[0]; }; enum @@ -408,9 +409,9 @@ set_rockridge (struct grub_iso9660_data *data) struct grub_fshelp_node rootnode; rootnode.data = data; - rootnode.alloc_dirents = 0; + rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* The 2nd data byte stored how many bytes are skipped every time @@ -500,7 +501,10 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - return node->symlink ? grub_strdup (node->symlink) : grub_strdup (""); + return node->have_symlink + ? grub_strdup (node->symlink + + (node->have_dirents) * sizeof (node->dirents[0]) + - sizeof (node->dirents)) : grub_strdup (""); } static grub_off_t @@ -703,7 +707,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* Setup a new node. */ node->data = dir->data; - node->symlink = symlink; + node->have_symlink = 0; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ @@ -767,10 +771,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, { struct grub_fshelp_node *new_node; node->alloc_dirents *= 2; - new_node = grub_malloc (sizeof (struct grub_fshelp_node) - + ((node->alloc_dirents - - ARRAY_SIZE (node->dirents)) - * sizeof (node->dirents[0]))); + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); if (!new_node) { if (filename_alloc) @@ -778,9 +783,37 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_free (node); return 0; } + node = new_node; } node->dirents[node->have_dirents++] = dirent; } + if (symlink) + { + if ((node->alloc_dirents - node->have_dirents) + * sizeof (node->dirents[0]) < grub_strlen (symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) + + grub_strlen (symlink) + 1); + if (!new_node) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) + - sizeof (node->dirents), symlink); + grub_free (symlink); + } if (hook (filename, type, node)) { if (filename_alloc) @@ -832,7 +865,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ @@ -875,7 +908,7 @@ grub_iso9660_open (struct grub_file *file, const char *name) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ From 33f784e88175d449eab915d74020cb6cd581b333 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 10 Nov 2011 09:41:07 +0100 Subject: [PATCH 186/315] Allow all modules to perform serial IO * grub-core/term-serial.c (grub_serial_find): Remove static qualifier * include/grub/serial.h (grub_serial_port_configure): New inline function. (grub_serial_port_fetch): Likewise. (grub_serial_port_put): Likewise. (grub_serial_port_fini): Likewise. (grub_serial_find): New proto. --- ChangeLog | 12 ++++++++++++ grub-core/term/serial.c | 2 +- include/grub/serial.h | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f293e0773..6c7304387 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-11-10 Shea Levy + + Allow all modules to perform serial IO + + * grub-core/term-serial.c (grub_serial_find): Remove static qualifier + * include/grub/serial.h (grub_serial_port_configure): New inline + function. + (grub_serial_port_fetch): Likewise. + (grub_serial_port_put): Likewise. + (grub_serial_port_fini): Likewise. + (grub_serial_find): New proto. + 2011-11-10 Vladimir Serbinenko Put symlink at the end of the node and fix a potential diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 306694192..86935626c 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -125,7 +125,7 @@ static struct grub_term_output grub_serial_term_output = -static struct grub_serial_port * +struct grub_serial_port * grub_serial_find (char *name) { struct grub_serial_port *port; diff --git a/include/grub/serial.h b/include/grub/serial.h index 41b720891..49ac0623a 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -96,6 +96,32 @@ grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port); void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port); + /* Convenience functions to perform primitive operations on a port. */ +static inline grub_err_t +grub_serial_port_configure (struct grub_serial_port *port, + struct grub_serial_config *config) +{ + return port->driver->configure (port, config); +} + +static inline int +grub_serial_port_fetch (struct grub_serial_port *port) +{ + return port->driver->fetch (port); +} + +static inline void +grub_serial_port_put (struct grub_serial_port *port, const int c) +{ + port->driver->put (port, c); +} + +static inline void +grub_serial_port_fini (struct grub_serial_port *port) +{ + port->driver->fini (port); +} + /* Set default settings. */ static inline grub_err_t grub_serial_config_defaults (struct grub_serial_port *port) @@ -117,6 +143,7 @@ grub_serial_config_defaults (struct grub_serial_port *port) void grub_ns8250_init (void); char *grub_serial_ns8250_add_port (grub_port_t port); +struct grub_serial_port *grub_serial_find (char *name); extern struct grub_serial_driver grub_ns8250_driver; void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); From 11a775a3ad55e6de651edcd71d344ea41e64d2eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:08:29 +0100 Subject: [PATCH 187/315] * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. --- ChangeLog | 4 ++++ grub-core/commands/probe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6c7304387..4e2d18c11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. + 2011-11-10 Shea Levy Allow all modules to perform serial IO diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index ce1e9aac0..a1d68cdeb 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -136,7 +136,7 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) return err; if (! label) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "uuid for this FS isn't supported yet"); + "label for this FS isn't supported yet"); if (state[0].set) grub_env_set (state[0].arg, label); From f768836950b038dbc67dabafb2a6086148edab82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:10:50 +0100 Subject: [PATCH 188/315] * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): A stylistic fix. --- ChangeLog | 5 +++++ grub-core/efiemu/main.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e2d18c11..fcbfe0c9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): + A stylistic fix. + 2011-11-11 Vladimir Serbinenko * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index 7ad3abb0d..126ecf9e7 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -149,7 +149,8 @@ grub_efiemu_register_configuration_table (grub_efi_guid_t guid, if (! get_table && ! data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must set at least get_table or data"); - if ((err = grub_efiemu_unregister_configuration_table (guid))) + err = grub_efiemu_unregister_configuration_table (guid); + if (err) return err; tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl)); From 6c1892942da03b61e5bfe74f670d3b5c33053152 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:13:23 +0100 Subject: [PATCH 189/315] * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. --- ChangeLog | 4 ++++ grub-core/fs/btrfs.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fcbfe0c9d..e37326afa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. + 2011-11-11 Vladimir Serbinenko * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index fae9199a4..db251ffd7 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1615,7 +1615,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), if (embed_type != GRUB_EMBED_PCBIOS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "BtrFS curently supports only PC-BIOS embedding"); + "BtrFS currently supports only PC-BIOS embedding"); if (64 * 2 - 1 < *nsectors) return grub_error (GRUB_ERR_OUT_OF_RANGE, From 53dc85906500ef6a23a37562c5619bf25ca6d7a2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:18:34 +0100 Subject: [PATCH 190/315] * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove leftover debug printf. --- ChangeLog | 5 +++++ grub-core/fs/ntfs.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e37326afa..2b2920b79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove + leftover debug printf. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 13de52cd8..ac695a29f 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -705,17 +705,18 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) switch (grub_cpu_to_le32 (symdesc.type)) { case 0xa000000c: - off = sizeof (struct symlink_descriptor) + 4 + grub_cpu_to_le32 (symdesc.off1); + off = (sizeof (struct symlink_descriptor) + 4 + + grub_cpu_to_le32 (symdesc.off1)); len = grub_cpu_to_le32 (symdesc.len1); break; case 0xa0000003: - off = sizeof (struct symlink_descriptor) + grub_cpu_to_le32 (symdesc.off1); + off = (sizeof (struct symlink_descriptor) + + grub_cpu_to_le32 (symdesc.off1)); len = grub_cpu_to_le32 (symdesc.len1); break; default: grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", grub_cpu_to_le32 (symdesc.type)); - grub_printf ("%d\n", __LINE__); return NULL; } From e2d22baf41ecd6252d9c7ca718d4906f37338cd9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:21:33 +0100 Subject: [PATCH 191/315] * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): Fix module name. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfscrypt.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b2920b79..0864781d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): + Fix module name. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 13f62b25a..619878243 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -455,7 +455,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) static grub_extcmd_t cmd_key; -GRUB_MOD_INIT(zfscrypto) +GRUB_MOD_INIT(zfscrypt) { grub_zfs_decrypt = grub_zfs_decrypt_real; grub_zfs_load_key = grub_zfs_load_key_real; @@ -465,7 +465,7 @@ GRUB_MOD_INIT(zfscrypto) options); } -GRUB_MOD_FINI(zfscrypto) +GRUB_MOD_FINI(zfscrypt) { grub_zfs_decrypt = 0; grub_zfs_load_key = 0; From 4c458569a7f1a7ac71c0d4f91820d45a227b3326 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:34:38 +0100 Subject: [PATCH 192/315] * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): Make buf a const. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/ieee1275.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0864781d7..f011fdef5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): + Make buf a const. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c index 9e2919172..b32fd2d8b 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/grub-core/kern/ieee1275/ieee1275.c @@ -532,7 +532,7 @@ grub_ieee1275_release (grub_addr_t addr, grub_size_t size) int grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle, - const char *propname, void *buf, + const char *propname, const void *buf, grub_size_t size, grub_ssize_t *actual) { struct set_property_args From 63a9e6f6a07bc07ae1df3c6917428cccfbf1fb71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:44:47 +0100 Subject: [PATCH 193/315] * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): Issue error rather than printf on unknown arguments. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/openfw.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f011fdef5..7c2b55e3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): + Issue error rather than printf on unknown arguments. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 57252d96b..3568ffe64 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -403,7 +403,8 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) break; default: unknown: - grub_printf ("Unsupported type %s for device %s\n", type, device); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported type %s for device %s", type, device); } fail: From 9bb182f3716cc9f850f5e64edb61a6da09748d7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:05:16 +0100 Subject: [PATCH 194/315] * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue an error and not a fatal on unrecognised relocation types. --- ChangeLog | 5 +++++ grub-core/kern/x86_64/dl.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c2b55e3b..b0a790c10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue + an error and not a fatal on unrecognised relocation types. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 090ad78b8..9b63b30f8 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -109,7 +109,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; default: - grub_fatal ("Unrecognized relocation: %d\n", ELF_R_TYPE (rel->r_info)); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "this relocation (%d) is not implemented yet", + ELF_R_TYPE (rel->r_info)); } } } From f7ce5bafb56ebeb2121c2d35eb98293f3e98acd0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:30:34 +0100 Subject: [PATCH 195/315] Fix mips compilation. * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec): Restrict hash_id to normal decoder. (hashes): Use in embed decoder as well (for sizes). (dec_stream_header): Fix embed decompressor logic. (dec_stream_footer): Likewise. --- ChangeLog | 10 ++++++++++ grub-core/lib/xzembed/xz_dec_stream.c | 19 ++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0a790c10..ca07d5cab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-11 Vladimir Serbinenko + + Fix mips compilation. + + * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec): Restrict hash_id to + normal decoder. + (hashes): Use in embed decoder as well (for sizes). + (dec_stream_header): Fix embed decompressor logic. + (dec_stream_footer): Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 383c29a2f..09e5e513a 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -78,9 +78,9 @@ struct xz_dec { #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; - grub_uint8_t hash_id; /* True if we are operating in single-call mode. */ bool single_call; @@ -428,8 +428,7 @@ static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, return XZ_STREAM_END; } -#ifndef GRUB_EMBED_DECOMPRESSOR -static struct +static const struct { const char *name; grub_size_t size; @@ -438,7 +437,6 @@ static struct [0x04] = { "CRC64", 8}, [0x0A] = { "SHA256", 32}, }; -#endif /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ static enum xz_ret dec_stream_header(struct xz_dec *s) @@ -470,9 +468,9 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) } #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] >= ARRAY_SIZE (hashes) @@ -482,7 +480,6 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1]; -#ifndef GRUB_EMBED_DECOMPRESSOR if (s->crc32) { s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL); @@ -530,17 +527,15 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) s->hash->init(s->index.hash.hash_context); s->hash->init(s->block.hash.hash_context); } -#else - s->hash = 0; -#endif -#if 1 if (!s->hash) return XZ_OPTIONS_ERROR; #endif } else { +#ifndef GRUB_EMBED_DECOMPRESSOR s->hash = 0; +#endif s->hash_size = 0; } @@ -589,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; +#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 From a8bd9d39d6fa19ee6672db9732a6f9f1a6d2502e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:32:06 +0100 Subject: [PATCH 196/315] * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): Fix prototype. --- ChangeLog | 5 +++++ include/grub/ieee1275/ieee1275.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca07d5cab..4838d9566 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): + Fix prototype. + 2011-11-11 Vladimir Serbinenko Fix mips compilation. diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 81590ee4b..be3835a42 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -173,7 +173,8 @@ int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size, unsigned int align, grub_addr_t *result); int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size); int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle, - const char *propname, void *buf, + const char *propname, + const void *buf, grub_size_t size, grub_ssize_t *actual); int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, From 067fdf005573500c6998402affe1723cd51efaf9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:02:51 +0100 Subject: [PATCH 197/315] * grub-core/kern/misc.c (grub_strstr): Moved from here ... * include/grub/misc.h (grub_strstr): ... here. Make static and inline. --- ChangeLog | 5 +++++ grub-core/kern/misc.c | 46 ----------------------------------------- include/grub/misc.h | 48 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4838d9566..6d740545a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_strstr): Moved from here ... + * include/grub/misc.h (grub_strstr): ... here. Make static and inline. + 2011-11-11 Vladimir Serbinenko * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index ebf80f100..34c9b3b0c 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -312,52 +312,6 @@ grub_strrchr (const char *s, int c) return p; } -/* Copied from gnulib. - Written by Bruno Haible , 2005. */ -char * -grub_strstr (const char *haystack, const char *needle) -{ - /* Be careful not to look at the entire extent of haystack or needle - until needed. This is useful because of these two cases: - - haystack may be very long, and a match of needle found early, - - needle may be very long, and not even a short initial segment of - needle may be found in haystack. */ - if (*needle != '\0') - { - /* Speed up the following searches of needle by caching its first - character. */ - char b = *needle++; - - for (;; haystack++) - { - if (*haystack == '\0') - /* No match. */ - return NULL; - if (*haystack == b) - /* The first character matches. */ - { - const char *rhaystack = haystack + 1; - const char *rneedle = needle; - - for (;; rhaystack++, rneedle++) - { - if (*rneedle == '\0') - /* Found a match. */ - return (char *) haystack; - if (*rhaystack == '\0') - /* No match. */ - return NULL; - if (*rhaystack != *rneedle) - /* Nothing in this round. */ - break; - } - } - } - } - else - return (char *) haystack; -} - int grub_strword (const char *haystack, const char *needle) { diff --git a/include/grub/misc.h b/include/grub/misc.h index 4e7d9077c..358f73258 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -113,7 +113,53 @@ int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); char *EXPORT_FUNC(grub_strchr) (const char *s, int c); char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); int EXPORT_FUNC(grub_strword) (const char *s, const char *w); -char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); + +/* Copied from gnulib. + Written by Bruno Haible , 2005. */ +static inline char * +grub_strstr (const char *haystack, const char *needle) +{ + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ + if (*needle != '\0') + { + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; + + for (;; haystack++) + { + if (*haystack == '\0') + /* No match. */ + return 0; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return 0; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; +} + int EXPORT_FUNC(grub_isspace) (int c); int EXPORT_FUNC(grub_isprint) (int c); From 9aed8a7178adb8c959fde3c3c3318478c8eab9ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:09:14 +0100 Subject: [PATCH 198/315] * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. --- ChangeLog | 4 ++++ grub-core/normal/main.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6d740545a..abf4dce28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/misc.c (grub_strstr): Moved from here ... diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index f372b6798..281b1f4bc 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -274,7 +274,6 @@ grub_normal_execute (const char *config, int nested, int batch) prefix = grub_env_get ("prefix"); read_lists (prefix); grub_register_variable_hook ("prefix", NULL, read_lists_hook); - grub_command_execute ("parser.grub", 0, 0); } if (config) From d35d0d3753cef291ed141d891f6c5e98dee929f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:34:37 +0100 Subject: [PATCH 199/315] Add const keyword to grub_env_get and gettextize week days. * grub-core/hook/datehook.c (grub_datetime_names): Make const. (grub_read_hook_datetime): Return const char *. * grub-core/kern/env.c (grub_env_get): Return const char *. All users updated. * grub-core/normal/datetime.c (grub_weekday_names): Make const. Mark for gettext. (grub_get_weekday_name): Return const char *. Call gettext. * grub-core/script/argv.c (grub_script_argv_append): Receive const char * and len as the argument. All users updated. (grub_script_argv_split_append): Receive const char *. * include/grub/datetime.h (grub_get_weekday_name): Update proto. * include/grub/env.h (grub_env_get): Likewise. (grub_env_read_hook_t): Return const char *. * include/grub/script_sh.h (grub_script_argv_append): Update proto. (grub_script_argv_split_append): Likewise. --- ChangeLog | 20 ++++++++++++++ grub-core/commands/i386/pc/drivemap.c | 2 +- grub-core/commands/legacycfg.c | 2 +- grub-core/commands/loadenv.c | 4 +-- grub-core/commands/wildcard.c | 2 +- grub-core/gettext/gettext.c | 2 +- grub-core/hook/datehook.c | 4 +-- grub-core/kern/dl.c | 2 +- grub-core/kern/env.c | 2 +- grub-core/kern/parser.c | 2 +- grub-core/lib/i386/pc/biosnum.c | 2 +- grub-core/loader/i386/linux.c | 7 ++--- grub-core/loader/i386/xnu.c | 2 +- grub-core/normal/datetime.c | 21 ++++++++------- grub-core/normal/menu.c | 4 +-- grub-core/script/argv.c | 25 ++++++++--------- grub-core/script/execute.c | 39 ++++++++++++++++----------- include/grub/datetime.h | 2 +- include/grub/env.h | 6 ++--- include/grub/script_sh.h | 5 ++-- 20 files changed, 91 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index abf4dce28..f98fd8e75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-11-11 Vladimir Serbinenko + + Add const keyword to grub_env_get and gettextize week days. + + * grub-core/hook/datehook.c (grub_datetime_names): Make const. + (grub_read_hook_datetime): Return const char *. + * grub-core/kern/env.c (grub_env_get): Return const char *. All users + updated. + * grub-core/normal/datetime.c (grub_weekday_names): Make const. + Mark for gettext. + (grub_get_weekday_name): Return const char *. Call gettext. + * grub-core/script/argv.c (grub_script_argv_append): Receive const + char * and len as the argument. All users updated. + (grub_script_argv_split_append): Receive const char *. + * include/grub/datetime.h (grub_get_weekday_name): Update proto. + * include/grub/env.h (grub_env_get): Likewise. + (grub_env_read_hook_t): Return const char *. + * include/grub/script_sh.h (grub_script_argv_append): Update proto. + (grub_script_argv_split_append): Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index c9c8881b4..9a89f968c 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -363,7 +363,7 @@ uninstall_int13_handler (void) static int grub_get_root_biosnumber_drivemap (void) { - char *biosnum; + const char *biosnum; int ret = -1; grub_device_t dev; diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index e68b3315a..4e87adafc 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -344,7 +344,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), int bsd_part = -1; { grub_device_t dev; - char *hdbiasstr; + const char *hdbiasstr; int hdbias = 0; hdbiasstr = grub_env_get ("legacy_hdbias"); if (hdbiasstr) diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 5d53a8e66..1073712d5 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -43,7 +43,7 @@ open_envblk_file (char *filename) if (! filename) { - char *prefix; + const char *prefix; prefix = grub_env_get ("prefix"); if (prefix) @@ -346,7 +346,7 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) while (argc) { - char *value; + const char *value; value = grub_env_get (args[0]); if (value) diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 256c07e51..d991b2010 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -436,7 +436,7 @@ wildcard_expand (const char *s, char ***strs) else if (*start == '/') /* no device part */ { - char *root; + const char *root; char *prefix; root = grub_env_get ("root"); diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 8581b1ff3..682754421 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -294,7 +294,7 @@ grub_mofile_open_lang (const char *locale_dir, const char *locale) static void grub_gettext_init_ext (const char *locale) { - char *locale_dir; + const char *locale_dir; if (!locale) return; diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index f64fac074..d7ceb85c8 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -26,7 +26,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static char *grub_datetime_names[] = +static const char *grub_datetime_names[] = { "YEAR", "MONTH", @@ -37,7 +37,7 @@ static char *grub_datetime_names[] = "WEEKDAY", }; -static char * +static const char * grub_read_hook_datetime (struct grub_env_var *var, const char *val __attribute__ ((unused))) { diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index b6fb537e8..26cf0d21d 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -697,7 +697,7 @@ grub_dl_load (const char *name) { char *filename; grub_dl_t mod; - char *grub_dl_dir = grub_env_get ("prefix"); + const char *grub_dl_dir = grub_env_get ("prefix"); mod = grub_dl_get (name); if (mod) diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c index 8f843a872..96b730d35 100644 --- a/grub-core/kern/env.c +++ b/grub-core/kern/env.c @@ -132,7 +132,7 @@ grub_env_set (const char *name, const char *val) return grub_errno; } -char * +const char * grub_env_get (const char *name) { struct grub_env_var *var; diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c index 6370a7b3a..5b449586c 100644 --- a/grub-core/kern/parser.c +++ b/grub-core/kern/parser.c @@ -123,7 +123,7 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, void add_var (grub_parser_state_t newstate) { - char *val; + const char *val; /* Check if a variable was being read in and the end of the name was reached. */ diff --git a/grub-core/lib/i386/pc/biosnum.c b/grub-core/lib/i386/pc/biosnum.c index 12771085a..0f0e743c4 100644 --- a/grub-core/lib/i386/pc/biosnum.c +++ b/grub-core/lib/i386/pc/biosnum.c @@ -24,7 +24,7 @@ static int grub_get_root_biosnumber_default (void) { - char *biosnum; + const char *biosnum; int ret = -1; grub_device_t dev; diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index fded7bb0a..a6eb95028 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -320,7 +320,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) void *framebuffer; grub_err_t err; grub_video_driver_id_t driver_id; - char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); + const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); driver_id = grub_video_get_driver_id (); @@ -418,14 +418,15 @@ grub_linux_boot (void) struct linux_kernel_params *params; int e820_num; grub_err_t err = 0; - char *modevar, *tmp; + const char *modevar; + char *tmp; struct grub_relocator32_state state; params = real_mode_mem; #ifdef GRUB_MACHINE_IEEE1275 { - char *bootpath; + const char *bootpath; grub_ssize_t len; bootpath = grub_env_get ("root"); diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 6128ec384..fa7af514b 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -700,7 +700,7 @@ grub_cpu_xnu_fill_devicetree (void) return grub_errno; /* First see if user supplies the value. */ - char *fsbvar = grub_env_get ("fsb"); + const char *fsbvar = grub_env_get ("fsb"); if (! fsbvar) *((grub_uint64_t *) curval->data) = 0; else diff --git a/grub-core/normal/datetime.c b/grub-core/normal/datetime.c index 44791e18c..8183601ba 100644 --- a/grub-core/normal/datetime.c +++ b/grub-core/normal/datetime.c @@ -18,16 +18,17 @@ */ #include +#include -static char *grub_weekday_names[] = +static const char *grub_weekday_names[] = { - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", + N_("Sunday"), + N_("Monday"), + N_("Tuesday"), + N_("Wednesday"), + N_("Thursday"), + N_("Friday"), + N_("Saturday"), }; int @@ -42,10 +43,10 @@ grub_get_weekday (struct grub_datetime *datetime) return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7; } -char * +const char * grub_get_weekday_name (struct grub_datetime *datetime) { - return grub_weekday_names[grub_get_weekday (datetime)]; + return _ (grub_weekday_names[grub_get_weekday (datetime)]); } #define SECPERMIN 60 diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 2c127794b..b75e9f523 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -79,7 +79,7 @@ grub_menu_get_entry (grub_menu_t menu, int no) int grub_menu_get_timeout (void) { - char *val; + const char *val; int timeout; val = grub_env_get ("timeout"); @@ -124,7 +124,7 @@ grub_menu_set_timeout (int timeout) static int get_and_remove_first_entry_number (const char *name) { - char *val; + const char *val; char *tail; int entry; diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c index 856828d7b..b58d3e658 100644 --- a/grub-core/script/argv.c +++ b/grub-core/script/argv.c @@ -66,7 +66,8 @@ grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args) struct grub_script_argv r = { 0, 0, 0 }; for (i = 0; i < argc; i++) - if (grub_script_argv_next (&r) || grub_script_argv_append (&r, args[i])) + if (grub_script_argv_next (&r) + || grub_script_argv_append (&r, args[i], grub_strlen (args[i]))) { grub_script_argv_free (&r); return 1; @@ -99,23 +100,23 @@ grub_script_argv_next (struct grub_script_argv *argv) /* Append `s' to the last argument. */ int -grub_script_argv_append (struct grub_script_argv *argv, const char *s) +grub_script_argv_append (struct grub_script_argv *argv, const char *s, + grub_size_t slen) { - int a; - int b; + grub_size_t a; char *p = argv->args[argv->argc - 1]; if (! s) return 0; a = p ? grub_strlen (p) : 0; - b = grub_strlen (s); - p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char))); + p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); if (! p) return 1; - grub_strcpy (p + a, s); + grub_memcpy (p + a, s, slen); + p[a+slen] = 0; argv->args[argv->argc - 1] = p; return 0; @@ -123,10 +124,9 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s) /* Split `s' and append words as multiple arguments. */ int -grub_script_argv_split_append (struct grub_script_argv *argv, char *s) +grub_script_argv_split_append (struct grub_script_argv *argv, const char *s) { - char ch; - char *p; + const char *p; int errors = 0; if (! s) @@ -138,10 +138,7 @@ grub_script_argv_split_append (struct grub_script_argv *argv, char *s) while (*s && ! grub_isspace (*s)) s++; - ch = *s; - *s = '\0'; - errors += grub_script_argv_append (argv, p); - *s = ch; + errors += grub_script_argv_append (argv, p, s - p); while (*s && grub_isspace (*s)) s++; diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 72d199760..1fb5de6a3 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -193,7 +193,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) if (! grub_env_special (name)) { - char *v = grub_env_get (name); + const char *v = grub_env_get (name); if (v && v[0]) { if (type == GRUB_SCRIPT_ARG_TYPE_VAR) @@ -202,20 +202,20 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, v)) + if (grub_script_argv_append (&result, v, grub_strlen (v))) goto fail; } } else if (! scope) { - if (grub_script_argv_append (&result, 0)) + if (grub_script_argv_append (&result, 0, 0)) goto fail; } else if (grub_strcmp (name, "#") == 0) { char buffer[ERRNO_DIGITS_MAX + 1]; grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); - if (grub_script_argv_append (&result, buffer)) + if (grub_script_argv_append (&result, buffer, grub_strlen (buffer))) goto fail; } else if (grub_strcmp (name, "*") == 0) @@ -231,10 +231,11 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else { - if (i != 0 && grub_script_argv_append (&result, " ")) + if (i != 0 && grub_script_argv_append (&result, " ", 1)) goto fail; - if (grub_script_argv_append (&result, scope->argv.args[i])) + if (grub_script_argv_append (&result, scope->argv.args[i], + grub_strlen (scope->argv.args[i]))) goto fail; } } @@ -251,7 +252,8 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, scope->argv.args[i])) + if (grub_script_argv_append (&result, scope->argv.args[i], + grub_strlen (scope->argv.args[i]))) goto fail; } } @@ -270,7 +272,9 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, scope->argv.args[num - 1])) + if (grub_script_argv_append (&result, scope->argv.args[num - 1], + grub_strlen (scope->argv.args[num - 1]) + )) goto fail; } } @@ -309,7 +313,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, char *p = 0; if (! grub_wildcard_translator || escape_type == 0) - return grub_script_argv_append (&result, s); + return grub_script_argv_append (&result, s, grub_strlen (s)); if (escape_type > 0) p = grub_wildcard_translator->escape (s); @@ -319,7 +323,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, if (! p) return 1; - r = grub_script_argv_append (&result, p); + r = grub_script_argv_append (&result, p, grub_strlen (p)); grub_free (p); return r; } @@ -344,7 +348,8 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR) { - if (grub_script_argv_append (&result, values[i])) + if (grub_script_argv_append (&result, values[i], + grub_strlen (values[i]))) goto fail; } else @@ -359,16 +364,18 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, break; case GRUB_SCRIPT_ARG_TYPE_BLOCK: - if (grub_script_argv_append (&result, "{") || - grub_script_argv_append (&result, arg->str) || - grub_script_argv_append (&result, "}")) + if (grub_script_argv_append (&result, "{", 1) + || grub_script_argv_append (&result, arg->str, + grub_strlen (arg->str)) + || grub_script_argv_append (&result, "}", 1)) goto fail; result.script = arg->script; break; case GRUB_SCRIPT_ARG_TYPE_TEXT: if (grub_strlen (arg->str) && - grub_script_argv_append (&result, arg->str)) + grub_script_argv_append (&result, arg->str, + grub_strlen (arg->str))) goto fail; break; @@ -680,7 +687,7 @@ grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd) { int ret; - char *result; + const char *result; struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd; /* Check if the commands results in a true or a false. The value is diff --git a/include/grub/datetime.h b/include/grub/datetime.h index 049dbc227..a7154fa1a 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -46,7 +46,7 @@ grub_err_t grub_set_datetime (struct grub_datetime *datetime); #endif int grub_get_weekday (struct grub_datetime *datetime); -char *grub_get_weekday_name (struct grub_datetime *datetime); +const char *grub_get_weekday_name (struct grub_datetime *datetime); void grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime); diff --git a/include/grub/env.h b/include/grub/env.h index c0107f16a..1ef11ecad 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -26,8 +26,8 @@ struct grub_env_var; -typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var, - const char *val); +typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var, + const char *val); typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, const char *val); @@ -43,7 +43,7 @@ struct grub_env_var }; grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); -char *EXPORT_FUNC(grub_env_get) (const char *name); +const char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var)); struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name); diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 6d31fca5a..fdccaca8d 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -245,8 +245,9 @@ void grub_script_mem_free (struct grub_script_mem *mem); void grub_script_argv_free (struct grub_script_argv *argv); int grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args); int grub_script_argv_next (struct grub_script_argv *argv); -int grub_script_argv_append (struct grub_script_argv *argv, const char *s); -int grub_script_argv_split_append (struct grub_script_argv *argv, char *s); +int grub_script_argv_append (struct grub_script_argv *argv, const char *s, + grub_size_t slen); +int grub_script_argv_split_append (struct grub_script_argv *argv, const char *s); struct grub_script_arglist * grub_script_create_arglist (struct grub_parser_param *state); From c1860f878be376b2778dc0590a94f8f8494a7c87 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:45:31 +0100 Subject: [PATCH 200/315] * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. (grub_xvasprintf): Likewise. --- ChangeLog | 5 +++++ grub-core/kern/misc.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index f98fd8e75..bdab31591 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. + (grub_xvasprintf): Likewise. + 2011-11-11 Vladimir Serbinenko Add const keyword to grub_env_get and gettextize week days. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 34c9b3b0c..8dd7f453f 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -216,6 +216,8 @@ grub_vprintf (const char *fmt, va_list args) s = grub_vsnprintf_real (curbuf, s, fmt, ap2); } + va_end (ap2); + grub_xputs (curbuf); if (curbuf != buf) @@ -911,6 +913,9 @@ grub_xvasprintf (const char *fmt, va_list ap) return NULL; s = grub_vsnprintf_real (ret, as, fmt, ap2); + + va_end (ap2); + if (s <= as) return ret; From 5b289bc5f6b48bdfb12a9a78779b4fef66d91d6e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:52:41 +0100 Subject: [PATCH 201/315] * util/grub-macho2img.c: Add comment concerning gettext. * grub-core/lib/legacy_parse.c: Likewise. --- ChangeLog | 5 +++++ grub-core/lib/legacy_parse.c | 3 +++ util/grub-macho2img.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index bdab31591..aaec2066b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * util/grub-macho2img.c: Add comment concerning gettext. + * grub-core/lib/legacy_parse.c: Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 659fa7061..43fca51dc 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -58,6 +58,9 @@ struct legacy_command 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", diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c index bce0a06d1..6dfb5fcbe 100644 --- a/util/grub-macho2img.c +++ b/util/grub-macho2img.c @@ -25,6 +25,8 @@ #include #include +/* Please don't internationalise this file. It's pointless. */ + /* XXX: this file assumes particular Mach-O layout and does no checks. */ /* However as build system ensures correct usage of this tool this shouldn't be a problem. */ From df067ad13af3c5722a0d7370d429415342d446a0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:59:25 +0100 Subject: [PATCH 202/315] * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into dprintf. * grub-core/font/font.c (grub_font_load): Likewise. --- ChangeLog | 6 ++++++ grub-core/efiemu/mm.c | 3 ++- grub-core/font/font.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index aaec2066b..e645709ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into + dprintf. + * grub-core/font/font.c (grub_font_load): Likewise. + 2011-11-11 Vladimir Serbinenko * util/grub-macho2img.c: Add comment concerning gettext. diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index 3c1dc2946..7bb7cc080 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -404,7 +404,8 @@ grub_efiemu_mmap_fill (void) GRUB_EFI_ACPI_MEMORY_NVS); default: - grub_printf ("Unknown memory type %d. Assuming unusable\n", type); + grub_dprintf ("efiemu", + "Unknown memory type %d. Assuming unusable\n", type); case GRUB_MEMORY_RESERVED: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_UNUSABLE_MEMORY); diff --git a/grub-core/font/font.c b/grub-core/font/font.c index 26eac4c05..3737480cf 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -608,7 +608,7 @@ grub_font_load (const char *filename) if (!font->name) { - grub_printf ("Note: Font has no name.\n"); + grub_dprintf ("font", "Font has no name.\n"); font->name = grub_strdup ("Unknown"); } From c76b54176213bb705badc31a434ec0229a45751e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:03:49 +0100 Subject: [PATCH 203/315] * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic fix. --- ChangeLog | 5 +++++ grub-core/hook/datehook.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e645709ef..be33b7660 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic + fix. + 2011-11-11 Vladimir Serbinenko * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index d7ceb85c8..ac75908ef 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -50,7 +50,7 @@ grub_read_hook_datetime (struct grub_env_var *var, int i; for (i = 0; i < 7; i++) - if (! grub_strcmp (var->name, grub_datetime_names[i])) + if (grub_strcmp (var->name, grub_datetime_names[i]) == 0) { int n; From 12d4f965cddb0625d2c6ada654463adefdef8bce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:14:41 +0100 Subject: [PATCH 204/315] Support %1$d syntax. * tests/printf_unit_test.c: New file. * Makefile.util.def (printf_test): New test. * grub-core/kern/misc.c (grub_vsnprintf_real): Support %1$d syntax. --- Makefile.util.def | 15 ++ grub-core/kern/misc.c | 484 ++++++++++++++++++++++++++------------- tests/printf_unit_test.c | 43 ++++ 3 files changed, 378 insertions(+), 164 deletions(-) create mode 100644 tests/printf_unit_test.c diff --git a/Makefile.util.def b/Makefile.util.def index 8742d1583..89e614468 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -660,6 +660,21 @@ program = { ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; +program = { + testcase; + name = printf_test; + common = tests/printf_unit_test.c; + common = tests/lib/unit_test.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/tests/lib/test.c; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +}; + program = { name = grub-menulst2cfg; mansection = 1; diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 8dd7f453f..128139dc8 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -637,10 +637,13 @@ grub_lltoa (char *str, int c, unsigned long long n) } static int -grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args) +grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list args_in) { char c; + grub_size_t n = 0; grub_size_t count = 0; + grub_size_t count_args = 0; + const char *fmt; auto void write_char (unsigned char ch); auto void write_str (const char *s); auto void write_fill (const char ch, int n); @@ -659,209 +662,362 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar write_char (*s++); } - void write_fill (const char ch, int n) + void write_fill (const char ch, int count_fill) { int i; - for (i = 0; i < n; i++) + for (i = 0; i < count_fill; i++) write_char (ch); } + fmt = fmt0; while ((c = *fmt++) != 0) { if (c != '%') - write_char (c); - else + continue; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + if (*fmt && *fmt == '$') + fmt++; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + if (*fmt && *fmt =='.') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + c = *fmt++; + if (c == 'l') { - char tmp[32]; - char *p; - unsigned int format1 = 0; - unsigned int format2 = ~ 0U; - char zerofill = ' '; - int rightfill = 0; - int n; - int longfmt = 0; - int longlongfmt = 0; - int unsig = 0; + c = *fmt++; + if (c == 'l') + c = *fmt++; + } + switch (c) + { + case 'p': + case 'x': + case 'u': + case 'd': + case 'c': + case 'C': + case 's': + count_args++; + break; + } + } - if (*fmt && *fmt =='-') + enum { INT, WCHAR, LONG, LONGLONG, POINTER } types[count_args]; + union + { + int i; + grub_uint32_t w; + long l; + long long ll; + void *p; + } args[count_args]; + + grub_memset (types, 0, sizeof (types)); + + fmt = fmt0; + n = 0; + while ((c = *fmt++) != 0) + { + int longfmt = 0; + int longlongfmt = 0; + grub_size_t curn; + const char *p; + + if (c != '%') + continue; + + curn = n++; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + p = fmt; + + if (*fmt && *fmt == '$') + { + curn = grub_strtoull (p, 0, 10) - 1; + fmt++; + } + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + c = *fmt++; + if (c == 'l') + { + c = *fmt++; + longfmt = 1; + if (c == 'l') { - rightfill = 1; - fmt++; + c = *fmt++; + longlongfmt = 1; } + } + if (curn >= count_args) + continue; + switch (c) + { + case 'x': + case 'u': + case 'd': + if (longlongfmt) + types[curn] = LONGLONG; + else if (longfmt) + types[curn] = LONG; + else + types[curn] = INT; + break; + case 'p': + case 's': + types[curn] = POINTER; + break; + case 'c': + types[curn] = INT; + break; + case 'C': + types[curn] = WCHAR; + break; + } + } - p = (char *) fmt; - /* Read formatting parameters. */ + for (n = 0; n < count_args; n++) + switch (types[n]) + { + case WCHAR: + args[n].w = va_arg (args_in, grub_uint32_t); + break; + case POINTER: + args[n].p = va_arg (args_in, void *); + break; + case INT: + args[n].i = va_arg (args_in, int); + break; + case LONG: + args[n].l = va_arg (args_in, long); + break; + case LONGLONG: + args[n].ll = va_arg (args_in, long long); + break; + } + + fmt = fmt0; + + n = 0; + while ((c = *fmt++) != 0) + { + char tmp[32]; + char *p; + unsigned int format1 = 0; + unsigned int format2 = ~ 0U; + char zerofill = ' '; + int rightfill = 0; + int longfmt = 0; + int longlongfmt = 0; + int unsig = 0; + grub_size_t curn; + + if (c != '%') + { + write_char (c); + continue; + } + + curn = n++; + + rescan:; + + if (*fmt && *fmt =='-') + { + rightfill = 1; + fmt++; + } + + p = (char *) fmt; + /* Read formatting parameters. */ + while (*p && grub_isdigit (*p)) + p++; + + if (p > fmt) + { + char s[p - fmt + 1]; + grub_strncpy (s, fmt, p - fmt); + s[p - fmt] = 0; + if (s[0] == '0') + zerofill = '0'; + format1 = grub_strtoul (s, 0, 10); + fmt = p; + } + + if (*p && *p == '.') + { + p++; + fmt++; while (*p && grub_isdigit (*p)) p++; if (p > fmt) { - char s[p - fmt + 1]; - grub_strncpy (s, fmt, p - fmt); - s[p - fmt] = 0; - if (s[0] == '0') - zerofill = '0'; - format1 = grub_strtoul (s, 0, 10); + char fstr[p - fmt + 1]; + grub_strncpy (fstr, fmt, p - fmt); + fstr[p - fmt] = 0; + format2 = grub_strtoul (fstr, 0, 10); fmt = p; } + } + if (*fmt == '$') + { + curn = format1 - 1; + fmt++; + format1 = 0; + format2 = ~ 0U; + zerofill = ' '; + rightfill = 0; - if (*p && *p == '.') - { - p++; - fmt++; - while (*p && grub_isdigit (*p)) - p++; - - if (p > fmt) - { - char fstr[p - fmt + 1]; - grub_strncpy (fstr, fmt, p - fmt); - fstr[p - fmt] = 0; - format2 = grub_strtoul (fstr, 0, 10); - fmt = p; - } - } + goto rescan; + } + c = *fmt++; + if (c == 'l') + { + longfmt = 1; c = *fmt++; if (c == 'l') { - longfmt = 1; + longlongfmt = 1; c = *fmt++; - if (c == 'l') - { - longlongfmt = 1; - c = *fmt++; - } } + } - switch (c) - { - case 'p': - write_str ("0x"); - c = 'x'; - longlongfmt |= (sizeof (void *) == sizeof (long long)); - /* Fall through. */ - case 'x': - case 'u': - unsig = 1; - /* Fall through. */ - case 'd': - if (longlongfmt) - { - long long ll; + if (curn >= count_args) + continue; - ll = va_arg (args, long long); - grub_lltoa (tmp, c, ll); - } - else if (longfmt && unsig) - { - unsigned long l = va_arg (args, unsigned long); - grub_lltoa (tmp, c, l); - } - else if (longfmt) - { - long l = va_arg (args, long); - grub_lltoa (tmp, c, l); - } - else if (unsig) - { - unsigned u = va_arg (args, unsigned); - grub_lltoa (tmp, c, u); - } - else - { - n = va_arg (args, int); - grub_lltoa (tmp, c, n); - } - if (! rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - write_str (tmp); - if (rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - break; + switch (c) + { + case 'p': + write_str ("0x"); + c = 'x'; + longlongfmt |= (sizeof (void *) == sizeof (long long)); + /* Fall through. */ + case 'x': + case 'u': + unsig = 1; + /* Fall through. */ + case 'd': + if (longlongfmt) + grub_lltoa (tmp, c, args[curn].ll); + else if (longfmt && unsig) + grub_lltoa (tmp, c, (unsigned long) args[curn].l); + else if (longfmt) + grub_lltoa (tmp, c, args[curn].l); + else if (unsig) + grub_lltoa (tmp, c, (unsigned) args[curn].i); + else + grub_lltoa (tmp, c, args[curn].i); + if (! rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + write_str (tmp); + if (rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + break; - case 'c': - n = va_arg (args, int); - write_char (n & 0xff); - break; + case 'c': + write_char (args[curn].i & 0xff); + break; - case 'C': + case 'C': + { + grub_uint32_t code = args[curn].w; + int shift; + unsigned mask; + + if (code <= 0x7f) { - grub_uint32_t code = va_arg (args, grub_uint32_t); - int shift; - unsigned mask; - - if (code <= 0x7f) - { - shift = 0; - mask = 0; - } - else if (code <= 0x7ff) - { - shift = 6; - mask = 0xc0; - } - else if (code <= 0xffff) - { - shift = 12; - mask = 0xe0; - } - else if (code <= 0x1fffff) - { - shift = 18; - mask = 0xf0; - } - else if (code <= 0x3ffffff) - { - shift = 24; - mask = 0xf8; - } - else if (code <= 0x7fffffff) - { - shift = 30; - mask = 0xfc; - } - else - { - code = '?'; - shift = 0; - mask = 0; - } - - write_char (mask | (code >> shift)); - - for (shift -= 6; shift >= 0; shift -= 6) - write_char (0x80 | (0x3f & (code >> shift))); + shift = 0; + mask = 0; + } + else if (code <= 0x7ff) + { + shift = 6; + mask = 0xc0; + } + else if (code <= 0xffff) + { + shift = 12; + mask = 0xe0; + } + else if (code <= 0x1fffff) + { + shift = 18; + mask = 0xf0; + } + else if (code <= 0x3ffffff) + { + shift = 24; + mask = 0xf8; + } + else if (code <= 0x7fffffff) + { + shift = 30; + mask = 0xfc; + } + else + { + code = '?'; + shift = 0; + mask = 0; } - break; - case 's': - p = va_arg (args, char *); - if (p) - { - grub_size_t len = 0; - while (len < format2 && p[len]) - len++; + write_char (mask | (code >> shift)); - if (!rightfill && len < format1) - write_fill (zerofill, format1 - len); + for (shift -= 6; shift >= 0; shift -= 6) + write_char (0x80 | (0x3f & (code >> shift))); + } + break; - grub_size_t i; - for (i = 0; i < len; i++) - write_char (*p++); + case 's': + p = args[curn].p; + if (p) + { + grub_size_t len = 0; + while (len < format2 && p[len]) + len++; - if (rightfill && len < format1) - write_fill (zerofill, format1 - len); - } - else - write_str ("(null)"); + if (!rightfill && len < format1) + write_fill (zerofill, format1 - len); - break; + grub_size_t i; + for (i = 0; i < len; i++) + write_char (*p++); - default: - write_char (c); - break; + if (rightfill && len < format1) + write_fill (zerofill, format1 - len); } + else + write_str ("(null)"); + + break; + + default: + write_char (c); + break; } } diff --git a/tests/printf_unit_test.c b/tests/printf_unit_test.c new file mode 100644 index 000000000..6e601b401 --- /dev/null +++ b/tests/printf_unit_test.c @@ -0,0 +1,43 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static void +printf_test (void) +{ + char real[512]; + char expected[512]; + grub_snprintf (real, sizeof (real), "%d %d %d", 1, 2, 3); + snprintf (expected, sizeof (expected), "%d %d %d", 1, 2, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%3$d %2$d %1$d", 1, 2, 3); + snprintf (expected, sizeof (expected), "%3$d %2$d %1$d", 1, 2, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%d %lld %d", 1, 2LL, 3); + snprintf (expected, sizeof (expected), "%d %lld %d", 1, 2LL, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%3$d %2$lld %1$d", 1, 2LL, 3); + snprintf (expected, sizeof (expected), "%3$d %2$lld %1$d", 1, 2LL, 3); + grub_test_assert (strcmp (real, expected) == 0); +} + +GRUB_UNIT_TEST ("printf_unit_test", printf_test); From 073aa7a9bf07d988b6337850f48599901089b9d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:22:02 +0100 Subject: [PATCH 205/315] Forgotten ChangeLog entry --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index be33b7660..725415cd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-11 Vladimir Serbinenko + + Support %1$d syntax. + + * tests/printf_unit_test.c: New file. + * Makefile.util.def (printf_test): New test. + * grub-core/kern/misc.c (grub_vsnprintf_real): Support %1$d syntax. + 2011-11-11 Vladimir Serbinenko * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic From 6e0632e28cd692faae2b026bb987e69906d6326a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:44:56 +0100 Subject: [PATCH 206/315] * grub-core/commands/acpihalt.c: Gettextized. * grub-core/commands/cacheinfo.c: Likewise. * grub-core/commands/cmp.c: Likewise. * grub-core/commands/efi/loadbios.c: Likewise. * grub-core/commands/gptsync.c: Likewise. * grub-core/commands/ieee1275/suspend.c: Likewise. * grub-core/commands/legacycfg.c: Likewise. * grub-core/commands/memrw.c: Likewise. * grub-core/commands/minicmd.c: Likewise. * grub-core/commands/parttool.c: Likewise. * grub-core/commands/time.c: Likewise. * grub-core/commands/videoinfo.c: Likewise. * grub-core/disk/geli.c: Likewise. * grub-core/disk/i386/pc/biosdisk.c: Likewise. * grub-core/disk/luks.c: Likewise. * grub-core/disk/lvm.c: Likewise. * grub-core/font/font_cmd.c: Likewise. * grub-core/fs/zfs/zfscrypt.c: Likewise. * grub-core/fs/zfs/zfsinfo.c: Likewise. * grub-core/gfxmenu/view.c: Likewise. * grub-core/kern/emu/hostdisk.c: Likewise. * grub-core/kern/emu/main.c: Likewise. * grub-core/kern/emu/misc.c: Likewise. * grub-core/kern/emu/mm.c: Likewise. * grub-core/kern/mips/arc/init.c: Likewise. * grub-core/kern/mips/loongson/init.c: Likewise. * grub-core/kern/partition.c: Likewise. * grub-core/lib/i386/halt.c: Likewise. * grub-core/lib/mips/arc/reboot.c: Likewise. * grub-core/lib/mips/loongson/reboot.c: Likewise. * grub-core/loader/i386/pc/chainloader.c: Likewise. * grub-core/loader/i386/xnu.c: Likewise. * grub-core/loader/multiboot.c: Likewise. * grub-core/net/bootp.c: Likewise. * grub-core/net/net.c: Likewise. * grub-core/normal/term.c: Likewise. * grub-core/partmap/bsdlabel.c: Likewise. * grub-core/parttool/msdospart.c: Likewise. * grub-core/term/gfxterm.c: Likewise. * grub-core/term/terminfo.c: Likewise. * grub-core/video/i386/pc/vbe.c: Likewise. * util/grub-menulst2cfg.c: Likewise. * util/grub-mkdevicemap.c: Likewise. * util/grub-mklayout.c: Likewise. * util/grub-mkrelpath.c: Likewise. * util/grub-script-check.c: Likewise. * util/ieee1275/grub-ofpathname.c: Likewise. * util/resolve.c: Likewise. --- ChangeLog | 51 ++++++++++++++++ grub-core/commands/acpihalt.c | 3 +- grub-core/commands/cacheinfo.c | 4 +- grub-core/commands/cmp.c | 19 +++--- grub-core/commands/efi/loadbios.c | 6 +- grub-core/commands/gptsync.c | 2 +- grub-core/commands/ieee1275/suspend.c | 2 +- grub-core/commands/legacycfg.c | 2 +- grub-core/commands/memrw.c | 2 +- grub-core/commands/minicmd.c | 2 +- grub-core/commands/parttool.c | 14 ++--- grub-core/commands/time.c | 4 +- grub-core/commands/videoinfo.c | 65 ++++++++++---------- grub-core/disk/geli.c | 14 ++--- grub-core/disk/i386/pc/biosdisk.c | 3 +- grub-core/disk/luks.c | 6 +- grub-core/disk/lvm.c | 3 +- grub-core/font/font_cmd.c | 2 +- grub-core/fs/zfs/zfscrypt.c | 6 +- grub-core/fs/zfs/zfsinfo.c | 83 +++++++++++++------------- grub-core/gfxmenu/view.c | 3 +- grub-core/kern/emu/hostdisk.c | 20 +++---- grub-core/kern/emu/main.c | 10 ++-- grub-core/kern/emu/misc.c | 6 +- grub-core/kern/emu/mm.c | 2 +- grub-core/kern/mips/arc/init.c | 5 +- grub-core/kern/mips/loongson/init.c | 3 +- grub-core/kern/partition.c | 3 +- grub-core/lib/i386/halt.c | 3 +- grub-core/lib/mips/arc/reboot.c | 3 +- grub-core/lib/mips/loongson/reboot.c | 3 +- grub-core/loader/i386/pc/chainloader.c | 2 +- grub-core/loader/i386/xnu.c | 2 +- grub-core/loader/multiboot.c | 2 +- grub-core/net/bootp.c | 4 +- grub-core/net/net.c | 8 +-- grub-core/normal/term.c | 5 +- grub-core/partmap/bsdlabel.c | 3 +- grub-core/parttool/msdospart.c | 13 ++-- grub-core/term/gfxterm.c | 5 +- grub-core/term/terminfo.c | 2 +- grub-core/video/i386/pc/vbe.c | 17 +++--- util/grub-menulst2cfg.c | 7 ++- util/grub-mkdevicemap.c | 8 +-- util/grub-mklayout.c | 16 ++--- util/grub-mkrelpath.c | 10 ++-- util/grub-script-check.c | 10 ++-- util/ieee1275/grub-ofpathname.c | 2 +- util/resolve.c | 5 +- 49 files changed, 275 insertions(+), 200 deletions(-) diff --git a/ChangeLog b/ChangeLog index 725415cd0..c3c0cfe61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,54 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/acpihalt.c: Gettextized. + * grub-core/commands/cacheinfo.c: Likewise. + * grub-core/commands/cmp.c: Likewise. + * grub-core/commands/efi/loadbios.c: Likewise. + * grub-core/commands/gptsync.c: Likewise. + * grub-core/commands/ieee1275/suspend.c: Likewise. + * grub-core/commands/legacycfg.c: Likewise. + * grub-core/commands/memrw.c: Likewise. + * grub-core/commands/minicmd.c: Likewise. + * grub-core/commands/parttool.c: Likewise. + * grub-core/commands/time.c: Likewise. + * grub-core/commands/videoinfo.c: Likewise. + * grub-core/disk/geli.c: Likewise. + * grub-core/disk/i386/pc/biosdisk.c: Likewise. + * grub-core/disk/luks.c: Likewise. + * grub-core/disk/lvm.c: Likewise. + * grub-core/font/font_cmd.c: Likewise. + * grub-core/fs/zfs/zfscrypt.c: Likewise. + * grub-core/fs/zfs/zfsinfo.c: Likewise. + * grub-core/gfxmenu/view.c: Likewise. + * grub-core/kern/emu/hostdisk.c: Likewise. + * grub-core/kern/emu/main.c: Likewise. + * grub-core/kern/emu/misc.c: Likewise. + * grub-core/kern/emu/mm.c: Likewise. + * grub-core/kern/mips/arc/init.c: Likewise. + * grub-core/kern/mips/loongson/init.c: Likewise. + * grub-core/kern/partition.c: Likewise. + * grub-core/lib/i386/halt.c: Likewise. + * grub-core/lib/mips/arc/reboot.c: Likewise. + * grub-core/lib/mips/loongson/reboot.c: Likewise. + * grub-core/loader/i386/pc/chainloader.c: Likewise. + * grub-core/loader/i386/xnu.c: Likewise. + * grub-core/loader/multiboot.c: Likewise. + * grub-core/net/bootp.c: Likewise. + * grub-core/net/net.c: Likewise. + * grub-core/normal/term.c: Likewise. + * grub-core/partmap/bsdlabel.c: Likewise. + * grub-core/parttool/msdospart.c: Likewise. + * grub-core/term/gfxterm.c: Likewise. + * grub-core/term/terminfo.c: Likewise. + * grub-core/video/i386/pc/vbe.c: Likewise. + * util/grub-menulst2cfg.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-mklayout.c: Likewise. + * util/grub-mkrelpath.c: Likewise. + * util/grub-script-check.c: Likewise. + * util/ieee1275/grub-ofpathname.c: Likewise. + * util/resolve.c: Likewise. + 2011-11-11 Vladimir Serbinenko Support %1$d syntax. diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 9a4cda521..177ec15f0 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -33,6 +33,7 @@ typedef uint8_t grub_uint8_t; #endif #include +#include #ifndef GRUB_DSDT_TEST #include @@ -327,6 +328,6 @@ grub_acpi_halt (void) grub_millisleep (1500); - grub_printf ("ACPI shutdown failed\n"); + grub_puts_ (N_("ACPI shutdown failed")); } #endif diff --git a/grub-core/commands/cacheinfo.c b/grub-core/commands/cacheinfo.c index 771763c9c..92aaa218d 100644 --- a/grub-core/commands/cacheinfo.c +++ b/grub-core/commands/cacheinfo.c @@ -31,14 +31,14 @@ grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), unsigned long hits, misses; grub_disk_cache_get_performance (&hits, &misses); - grub_printf ("Disk cache: hits = %lu, misses = %lu ", hits, misses); + grub_printf_ (N_("Disk cache: hits = %lu, misses = %lu "), hits, misses); if (hits + misses) { unsigned long ratio = hits * 10000 / (hits + misses); grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100); } else - grub_printf ("(N/A)\n"); + grub_puts_ (N_("(N/A)")); return 0; } diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index 526459311..5d5925dd5 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -42,8 +42,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); - grub_printf ("Compare file `%s' with `%s':\n", args[0], - args[1]); + grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], + args[1]); file1 = grub_file_open (args[0]); file2 = grub_file_open (args[1]); @@ -51,9 +51,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), goto cleanup; if (grub_file_size (file1) != grub_file_size (file2)) - grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n", - (unsigned long long) grub_file_size (file1), args[0], - (unsigned long long) grub_file_size (file2), args[1]); + grub_printf_ (N_("Files differ in size: %llu [%s], %llu [%s]\n"), + (unsigned long long) grub_file_size (file1), args[0], + (unsigned long long) grub_file_size (file2), args[1]); else { pos = 0; @@ -78,9 +78,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), { if (buf1[i] != buf2[i]) { - grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n", - (unsigned long long) (i + pos), buf1[i], args[0], - buf2[i], args[1]); + grub_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"), + (unsigned long long) (i + pos), buf1[i], + args[0], buf2[i], args[1]); goto cleanup; } } @@ -89,7 +89,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), } while (rd2); - grub_printf ("The files are identical.\n"); + /* TRANSLATORS: it's always exactly 2 files. */ + grub_printf_ (N_("The files are identical.\n")); } cleanup: diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c index 138311222..5eb490fd4 100644 --- a/grub-core/commands/efi/loadbios.c +++ b/grub-core/commands/efi/loadbios.c @@ -49,7 +49,7 @@ enable_rom_area (void) rom_ptr = (grub_uint32_t *) VBIOS_ADDR; if (*rom_ptr != BLANK_MEM) { - grub_printf ("ROM image is present.\n"); + grub_puts_ (N_("ROM image is present.")); return 0; } @@ -67,7 +67,7 @@ enable_rom_area (void) *rom_ptr = 0; if (*rom_ptr != 0) { - grub_printf ("Can\'t enable ROM area.\n"); + grub_puts_ (N_("Can\'t enable ROM area.")); return 0; } @@ -209,7 +209,7 @@ GRUB_MOD_INIT(loadbios) 0, N_("Fake BIOS.")); cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, - "BIOS_DUMP [INT10_DUMP]", + N_("BIOS_DUMP [INT10_DUMP]"), N_("Load BIOS dump.")); } diff --git a/grub-core/commands/gptsync.c b/grub-core/commands/gptsync.c index e92dc20ec..88d4b6296 100644 --- a/grub-core/commands/gptsync.c +++ b/grub-core/commands/gptsync.c @@ -231,7 +231,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - grub_printf ("New MBR is written to '%s'\n", args[0]); + grub_printf_ (N_("New MBR is written to '%s'\n"), args[0]); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/ieee1275/suspend.c b/grub-core/commands/ieee1275/suspend.c index de068951d..844485077 100644 --- a/grub-core/commands/ieee1275/suspend.c +++ b/grub-core/commands/ieee1275/suspend.c @@ -31,7 +31,7 @@ grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_printf ("Run 'go' to resume GRUB.\n"); + grub_puts_ (N_("Run 'go' to resume GRUB.")); grub_ieee1275_enter (); grub_cls (); return 0; diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 4e87adafc..4de2d84d5 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -723,7 +723,7 @@ grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unuse if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); - grub_printf ("Enter password:"); + grub_puts_ (N_("Enter password: ")); if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) return GRUB_ACCESS_DENIED; diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 3b51189d6..5984288ce 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -31,7 +31,7 @@ static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; static const struct grub_arg_option options[] = { {0, 'v', 0, N_("Save read value into variable VARNAME."), - "VARNAME", ARG_TYPE_STRING}, + N_("VARNAME"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index b9cbd06c1..1bb0147df 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -145,7 +145,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), { grub_dl_t mod; - grub_printf ("Name\tRef Count\tDependencies\n"); + grub_printf_ (N_("Name\tRef Count\tDependencies\n")); FOR_DL_MODULES (mod) { grub_dl_dep_t dep; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index a54286161..ab5ab5ea4 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -37,9 +37,9 @@ static struct grub_parttool *parts = 0; static int curhandle = 0; static grub_dl_t mymod; static char helpmsg[] = - "Perform COMMANDS on partition.\n" - "Use \"parttool PARTITION help\" for the list " - "of available commands."; + N_("Perform COMMANDS on partition.\n" + "Use \"parttool PARTITION help\" for the list " + "of available commands."); int grub_parttool_register(const char *part_name, @@ -128,7 +128,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), break; case GRUB_PARTTOOL_ARG_VAL: - grub_printf ("=VAL"); + grub_xputs (_("=VAL")); spacing -= 4; break; @@ -137,18 +137,18 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } while (spacing-- > 0) grub_printf (" "); - grub_printf ("%s\n", curarg->desc); + grub_puts_ (curarg->desc); } } if (! found) - grub_printf ("Sorry no parttool is available for %s\n", + grub_printf_ (N_("Sorry no parttool is available for %s\n"), dev->disk->partition->partmap->name); return GRUB_ERR_NONE; } if (argc < 1) { - grub_printf ("%s\n", helpmsg); + grub_puts_ (helpmsg); return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments"); } diff --git a/grub-core/commands/time.c b/grub-core/commands/time.c index 687495964..224f92b3f 100644 --- a/grub-core/commands/time.c +++ b/grub-core/commands/time.c @@ -47,8 +47,8 @@ grub_cmd_time (grub_command_t ctxt __attribute__ ((unused)), (cmd->func) (cmd, argc - 1, &args[1]); end = grub_get_time_ms (); - grub_printf ("Elapsed time: %d.%03d seconds \n", (end - start) / 1000, - (end - start) % 1000); + grub_printf_ (N_("Elapsed time: %d.%03d seconds \n"), (end - start) / 1000, + (end - start) % 1000); return grub_errno; } diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 7ff172fd7..9e12ff55e 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -52,36 +52,36 @@ hook (const struct grub_video_mode_info *info) grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) - grub_printf ("Text-only "); + grub_xputs (_("Text-only ")); /* Show mask and position details for direct color modes. */ if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) - grub_printf ("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d", - info->red_mask_size, - info->green_mask_size, - info->blue_mask_size, - info->reserved_mask_size, - info->red_field_pos, - info->green_field_pos, - info->blue_field_pos, - info->reserved_field_pos); + grub_printf_ (N_("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d"), + info->red_mask_size, + info->green_mask_size, + info->blue_mask_size, + info->reserved_mask_size, + info->red_field_pos, + info->green_field_pos, + info->blue_field_pos, + info->reserved_field_pos); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - grub_printf ("Packed "); + grub_xputs (_("Packed ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV) - grub_printf ("YUV "); + grub_xputs (_("YUV ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR) - grub_printf ("Planar "); + grub_xputs (_("Planar ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES) - grub_printf ("Hercules "); + grub_xputs (_("Hercules ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA) - grub_printf ("CGA "); + grub_xputs (_("CGA ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4) - grub_printf ("Non-chain 4 "); + grub_xputs (_("Non-chain 4 ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) - grub_printf ("Monochrome "); + grub_xputs (_("Monochrome ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN) - grub_printf ("Unknown "); + grub_xputs (_("Unknown ")); - grub_printf ("\n"); + grub_xputs ("\n"); return 0; } @@ -93,19 +93,19 @@ print_edid (struct grub_video_edid_info *edid_info) if (grub_video_edid_checksum (edid_info)) { - grub_printf (" EDID checksum invalid\n"); + grub_puts_ (N_(" EDID checksum invalid")); grub_errno = GRUB_ERR_NONE; return; } - grub_printf (" EDID version: %u.%u\n", - edid_info->version, edid_info->revision); + grub_printf_ (N_(" EDID version: %u.%u\n"), + edid_info->version, edid_info->revision); if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height) == GRUB_ERR_NONE) - grub_printf (" Preferred mode: %ux%u\n", edid_width, edid_height); + grub_printf_ (N_(" Preferred mode: %ux%u\n"), edid_width, edid_height); else { - grub_printf (" No preferred mode available\n"); + grub_printf_ (N_(" No preferred mode available\n")); grub_errno = GRUB_ERR_NONE; } } @@ -147,20 +147,20 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), id = grub_video_get_driver_id (); - grub_printf ("List of supported video modes:\n"); - grub_printf ("Legend: P=Packed pixel, D=Direct color, " - "mask/pos=R/G/B/reserved\n"); + grub_puts_ (N_("List of supported video modes:")); + grub_puts_ (N_("Legend: P=Packed pixel, D=Direct color, " + "mask/pos=R/G/B/reserved")); FOR_VIDEO_ADAPTERS (adapter) { struct grub_video_mode_info info; struct grub_video_edid_info edid_info; - grub_printf ("Adapter '%s':\n", adapter->name); + grub_printf_ (N_("Adapter '%s':\n"), adapter->name); if (!adapter->iterate) { - grub_printf (" No info available\n"); + grub_puts_ (N_(" No info available")); continue; } @@ -178,7 +178,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), { if (adapter->init ()) { - grub_printf (" Failed\n"); + grub_puts_ (N_(" Failed")); grub_errno = GRUB_ERR_NONE; continue; } @@ -215,12 +215,13 @@ static grub_command_t cmd_vbe; GRUB_MOD_INIT(videoinfo) { - cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, "[WxH[xD]]", + cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); #ifdef GRUB_MACHINE_PCBIOS - cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, "[WxH[xD]]", + cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, + N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index ab94b4131..d3137bc16 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -226,7 +226,7 @@ grub_util_get_geli_uuid (const char *dev) uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1); if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0) - grub_util_error ("couldn't read ELI metadata"); + grub_util_error (_("couldn't read ELI metadata")); COMPILE_TIME_ASSERT (sizeof (header) <= 512); header = (void *) &hdr; @@ -235,7 +235,7 @@ grub_util_get_geli_uuid (const char *dev) if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) || grub_le_to_cpu32 (header->version) > 5 || grub_le_to_cpu32 (header->version) < 1) - grub_util_error ("wrong ELI magic or version"); + grub_util_error (_("wrong ELI magic or version")); err = make_uuid ((void *) &hdr, uuid); if (err) @@ -418,15 +418,15 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) keysize = grub_le_to_cpu16 (header.keylen) / 8; grub_memset (zero, 0, sizeof (zero)); - grub_printf ("Attempting to decrypt master key...\n"); + grub_puts_ (N_("Attempting to decrypt master key...")); /* Get the passphrase from the user. */ tmp = NULL; if (source->partition) tmp = grub_partition_get_name (source->partition); - grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, - source->partition ? "," : "", tmp ? : "", - dev->uuid); + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, + source->partition ? "," : "", tmp ? : "", + dev->uuid); grub_free (tmp); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); @@ -513,7 +513,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0) continue; - grub_printf ("Slot %d opened\n", i); + grub_printf_ (N_("Slot %d opened\n"), i); /* Set the master key. */ if (!dev->rekey) diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index e152b9d89..25f683fd1 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -625,7 +626,7 @@ GRUB_MOD_INIT(biosdisk) if (grub_disk_firmware_is_tainted) { - grub_printf ("Firmware is marked as tainted, refusing to initialize.\n"); + grub_puts_ (N_("Firmware is marked as tainted, refusing to initialize.")); return; } grub_disk_firmware_fini = grub_disk_biosdisk_fini; diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 0ec95fccd..a5c0d3418 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -316,7 +316,7 @@ luks_recover_key (grub_disk_t source, if (err) return err; - grub_printf ("Attempting to decrypt master key...\n"); + grub_puts_ (N_("Attempting to decrypt master key...")); keysize = grub_be_to_cpu32 (header.keyBytes); for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) @@ -332,7 +332,7 @@ luks_recover_key (grub_disk_t source, tmp = NULL; if (source->partition) tmp = grub_partition_get_name (source->partition); - grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, source->partition ? "," : "", tmp ? : "", dev->uuid); grub_free (tmp); @@ -434,7 +434,7 @@ luks_recover_key (grub_disk_t source, continue; } - grub_printf ("Slot %d opened\n", i); + grub_printf_ (N_("Slot %d opened\n"), i); /* Set the master key. */ gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 4020fc427..388c7f173 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -775,7 +776,7 @@ grub_lvm_memberlist (grub_disk_t disk) for (pv = lv->vg->pvs; pv; pv = pv->next) { if (!pv->disk) - grub_util_error ("Couldn't find PV %s. Check your device.map", + grub_util_error (_("Couldn't find PV %s. Check your device.map"), pv->name); tmp = grub_malloc (sizeof (*tmp)); tmp->disk = pv->disk; diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c index 98f0b88d6..b38eccd6d 100644 --- a/grub-core/font/font_cmd.c +++ b/grub-core/font/font_cmd.c @@ -49,7 +49,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), { struct grub_font_node *node; - grub_printf ("Loaded fonts:\n"); + grub_puts_ (N_("Loaded fonts:")); for (node = grub_font_list; node; node = node->next) { grub_font_t font = node->value; diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 619878243..63380f66a 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -421,7 +421,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) } else { - grub_printf ("Enter ZFS password: "); + grub_xputs (_("Enter ZFS password: ")); if (!grub_password_get ((char *) buf, 1023)) return grub_errno; real_size = grub_strlen ((char *) buf); @@ -460,8 +460,8 @@ GRUB_MOD_INIT(zfscrypt) grub_zfs_decrypt = grub_zfs_decrypt_real; grub_zfs_load_key = grub_zfs_load_key_real; cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, - "zfskey [-h|-p|-r] [FILE]", - "Import ZFS wrapping key stored in FILE.", + N_("[-h|-p|-r] [FILE]"), + N_("Import ZFS wrapping key stored in FILE."), options); } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 8c073fab5..94f2a1ac8 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -44,32 +45,32 @@ print_state (char *nvlist, int tab) int isok = 1; print_tabs (tab); - grub_printf ("State: "); + grub_xputs (_("State: ")); if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival)) { - grub_printf ("removed "); + grub_xputs (_("removed ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) { - grub_printf ("faulted "); + grub_xputs (_("faulted ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival)) { - grub_printf ("offline "); + grub_xputs (_("offline ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) - grub_printf ("degraded "); + grub_xputs (_("degraded ")); if (isok) - grub_printf ("online"); - grub_printf ("\n"); + grub_xputs (_("online")); + grub_xputs ("\n"); return GRUB_ERR_NONE; } @@ -84,7 +85,7 @@ print_vdev_info (char *nvlist, int tab) if (!type) { print_tabs (tab); - grub_printf ("Incorrect VDEV: no type available\n"); + grub_puts_ (N_("Incorrect VDEV: no type available")); return grub_errno; } @@ -95,7 +96,7 @@ print_vdev_info (char *nvlist, int tab) char *devid = 0; print_tabs (tab); - grub_printf ("Leaf VDEV\n"); + grub_puts_ (N_("Leaf VDEV")); print_state (nvlist, tab); @@ -103,23 +104,23 @@ print_vdev_info (char *nvlist, int tab) grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); print_tabs (tab); if (!bootpath) - grub_printf ("Bootpath: unavailable\n"); + grub_puts_ (N_("Bootpath: unavailable\n")); else - grub_printf ("Bootpath: %s\n", bootpath); + grub_printf_ (N_("Bootpath: %s\n"), bootpath); path = grub_zfs_nvlist_lookup_string (nvlist, "path"); print_tabs (tab); if (!path) - grub_printf ("Path: unavailable\n"); + grub_puts_ (N_("Path: unavailable")); else - grub_printf ("Path: %s\n", path); + grub_printf_ (N_("Path: %s\n"), path); devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); print_tabs (tab); if (!devid) - grub_printf ("Devid: unavailable\n"); + grub_puts_ (N_("Devid: unavailable")); else - grub_printf ("Devid: %s\n", devid); + grub_printf_ (N_("Devid: %s\n"), devid); grub_free (bootpath); grub_free (devid); grub_free (path); @@ -136,10 +137,10 @@ print_vdev_info (char *nvlist, int tab) print_tabs (tab); if (nelm <= 0) { - grub_printf ("Incorrect mirror VDEV\n"); + grub_puts_ (N_("Incorrect mirror VDEV")); return GRUB_ERR_NONE; } - grub_printf ("Mirror VDEV with %d children\n", nelm); + grub_printf_ (N_("Mirror VDEV with %d children\n"), nelm); print_state (nvlist, tab); for (i = 0; i < nelm; i++) { @@ -151,11 +152,11 @@ print_vdev_info (char *nvlist, int tab) print_tabs (tab); if (!child) { - grub_printf ("Mirror VDEV element %d isn't correct\n", i); + grub_printf_ (N_("Mirror VDEV element %d isn't correct\n"), i); continue; } - grub_printf ("Mirror VDEV element %d:\n", i); + grub_printf_ (N_("Mirror VDEV element %d:\n"), i); print_vdev_info (child, tab + 1); grub_free (child); @@ -164,7 +165,7 @@ print_vdev_info (char *nvlist, int tab) } print_tabs (tab); - grub_printf ("Unknown VDEV type: %s\n", type); + grub_printf_ (N_("Unknown VDEV type: %s\n"), type); return GRUB_ERR_NONE; } @@ -221,15 +222,15 @@ get_bootpath (char *nvlist, char **bootpath, char **devid) return GRUB_ERR_NONE; } -static char *poolstates[] = { - [POOL_STATE_ACTIVE] = "active", - [POOL_STATE_EXPORTED] = "exported", - [POOL_STATE_DESTROYED] = "destroyed", - [POOL_STATE_SPARE] = "reserved for hot spare", - [POOL_STATE_L2CACHE] = "level 2 ARC device", - [POOL_STATE_UNINITIALIZED] = "uninitialized", - [POOL_STATE_UNAVAIL] = "unavailable", - [POOL_STATE_POTENTIALLY_ACTIVE] = "potentially active" +static const char *poolstates[] = { + [POOL_STATE_ACTIVE] = N_("Pool state: active"), + [POOL_STATE_EXPORTED] = N_("Pool state: exported"), + [POOL_STATE_DESTROYED] = N_("Pool state: destroyed"), + [POOL_STATE_SPARE] = N_("Pool state: reserved for hot spare"), + [POOL_STATE_L2CACHE] = N_("Pool state: level 2 ARC device"), + [POOL_STATE_UNINITIALIZED] = N_("Pool state: uninitialized"), + [POOL_STATE_UNAVAIL] = N_("Pool state: unavailable"), + [POOL_STATE_POTENTIALLY_ACTIVE] = N_("Pool state: potentially active") }; static grub_err_t @@ -274,30 +275,30 @@ grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc, poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); if (!poolname) - grub_printf ("Pool name: unavailable\n"); + grub_puts_ (N_("Pool name: unavailable")); else - grub_printf ("Pool name: %s\n", poolname); + grub_printf_ (N_("Pool name: %s\n"), poolname); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); if (!found) - grub_printf ("Pool GUID: unavailable\n"); + grub_puts_ (N_("Pool GUID: unavailable")); else - grub_printf ("Pool GUID: %016llx\n", (long long unsigned) guid); + grub_printf_ (N_("Pool GUID: %016llx\n"), (long long unsigned) guid); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, &pool_state); if (!found) - grub_printf ("Unable to retrieve pool state\n"); + grub_puts_ (N_("Unable to retrieve pool state")); else if (pool_state >= ARRAY_SIZE (poolstates)) - grub_printf ("Unrecognized pool state\n"); + grub_puts_ (N_("Unrecognized pool state")); else - grub_printf ("Pool state: %s\n", poolstates[pool_state]); + grub_puts_ (poolstates[pool_state]); nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); if (!nv) - grub_printf ("No vdev tree available\n"); + grub_puts_ (N_("No vdev tree available")); else print_vdev_info (nv, 1); @@ -395,11 +396,11 @@ static grub_command_t cmd_info, cmd_bootfs; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, - "zfsinfo DEVICE", - "Print ZFS info about DEVICE."); + N_("DEVICE"), + N_("Print ZFS info about DEVICE.")); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, - "zfs-bootfs FILESYSTEM [VARIABLE]", - "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); + N_("FILESYSTEM [VARIABLE]"), + N_("Print ZFS-BOOTFSOBJ or set it to VARIABLE")); } GRUB_MOD_FINI (zfsinfo) diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c index 836a9884d..9023fd3c4 100644 --- a/grub-core/gfxmenu/view.c +++ b/grub-core/gfxmenu/view.c @@ -36,6 +36,7 @@ #include #include #include +#include static void init_terminal (grub_gfxmenu_view_t view); @@ -77,7 +78,7 @@ grub_gfxmenu_view_new (const char *theme_path, view->desktop_image = 0; view->desktop_color = default_bg_color; view->terminal_box = grub_gfxmenu_create_box (0, 0); - view->title_text = grub_strdup ("GRUB Boot Menu"); + view->title_text = grub_strdup (_("GRUB Boot Menu")); view->progress_message_text = 0; view->theme_path = 0; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7bfc66fef..f537b2759 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -269,7 +269,7 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) struct stat st; if (fstat (fd, &st) < 0) - grub_util_error ("fstat failed"); + grub_util_error (_("fstat failed")); #if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) \ @@ -324,7 +324,7 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) return minfo.dki_capacity; # else if (nr & ((1 << log_sector_size) - 1)) - grub_util_error ("unaligned device size"); + grub_util_error (_("unaligned device size")); return (nr >> log_sector_size); # endif @@ -373,7 +373,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) size = grub_util_get_disk_size (map[drive].device); if (size % 512) - grub_util_error ("unaligned device size"); + grub_util_error (_("unaligned device size")); disk->total_sectors = size >> 9; @@ -442,13 +442,13 @@ grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **n error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) if (strcasecmp (class->lg_name, "part") == 0) break; if (!class) - grub_util_error ("couldn't open geom part"); + grub_util_error (_("couldn't open geom part")); LIST_FOREACH (geom, &class->lg_geom, lg_geom) { @@ -1144,18 +1144,18 @@ read_device_map (const char *dev_map) continue; if (*p != '(') - show_error ("No open parenthesis found"); + show_error (_("No open parenthesis found")); p++; /* Find a free slot. */ drive = find_free_slot (); if (drive < 0) - show_error ("Map table size exceeded"); + show_error (_("Map table size exceeded")); e = p; p = strchr (p, ')'); if (! p) - show_error ("No close parenthesis found"); + show_error (_("No close parenthesis found")); map[drive].drive = xmalloc (p - e + sizeof ('\0')); strncpy (map[drive].drive, e, p - e + sizeof ('\0')); @@ -1167,7 +1167,7 @@ read_device_map (const char *dev_map) p++; if (*p == '\0') - show_error ("No filename found"); + show_error (_("No filename found")); /* NUL-terminate the filename. */ e = p; @@ -1196,7 +1196,7 @@ read_device_map (const char *dev_map) { map[drive].device = xmalloc (PATH_MAX); if (! realpath (p, map[drive].device)) - grub_util_error ("cannot get the real path of `%s'", p); + grub_util_error (_("cannot get the real path of `%s'"), p); } else #endif diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 8d15f17c5..725d1ac7f 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -98,10 +98,10 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else printf ( - "Usage: %s [OPTION]...\n" + _("Usage: %s [OPTION]...\n" "\n" "GRUB emulator.\n" "\n" @@ -113,7 +113,7 @@ usage (int status) " -h, --help display this message and exit\n" " -V, --version print version information and exit\n" "\n" - "Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); + "Report bugs to <%s>.\n"), program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); return status; } @@ -166,13 +166,13 @@ main (int argc, char *argv[]) if (optind < argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind]); return usage (1); } /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ if (hold && verbosity > 0) - printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n", + printf (_("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n"), program_name, (int) getpid ()); while (hold) { diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 6f5ea9fb9..21f314d55 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -117,7 +117,7 @@ xmalloc (grub_size_t size) p = malloc (size); if (! p) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return p; } @@ -127,7 +127,7 @@ xrealloc (void *ptr, grub_size_t size) { ptr = realloc (ptr, size); if (! ptr) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return ptr; } @@ -185,7 +185,7 @@ xasprintf (const char *fmt, ...) if (vasprintf (&result, fmt, ap) < 0) { if (errno == ENOMEM) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return NULL; } diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c index 6a70efb4c..b58ccc794 100644 --- a/grub-core/kern/emu/mm.c +++ b/grub-core/kern/emu/mm.c @@ -77,7 +77,7 @@ grub_memalign (grub_size_t align, grub_size_t size) #else (void) align; (void) size; - grub_util_error ("grub_memalign is not supported"); + grub_util_error (_("grub_memalign is not supported")); #endif if (!p) diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index ec0fa521a..41545b11f 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -33,6 +33,7 @@ #include #include #include +#include const char *type_names[] = { #ifdef GRUB_CPU_WORDS_BIGENDIAN @@ -178,7 +179,7 @@ grub_halt (void) grub_millisleep (1500); - grub_printf ("Shutdown failed\n"); + grub_puts_ (N_("Shutdown failed")); grub_refresh (); while (1); } @@ -190,7 +191,7 @@ grub_exit (void) grub_millisleep (1500); - grub_printf ("Exit failed\n"); + grub_puts_ (N_("Exit failed")); grub_refresh (); while (1); } diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 6ddf151f2..3b282e1e0 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -31,6 +31,7 @@ #include #include #include +#include extern void grub_video_sm712_init (void); extern void grub_video_sis315pro_init (void); @@ -254,7 +255,7 @@ grub_halt (void) break; } - grub_printf ("Shutdown failed\n"); + grub_puts_ (N_("Shutdown failed")); grub_refresh (); while (1); } diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index a2f5dd722..cd9e8ae0f 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -47,7 +48,7 @@ grub_partition_check_containment (const grub_disk_t disk, grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", part->partmap->name, part->number + 1, disk->name, partname); #ifdef GRUB_UTIL - grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), disk->name, partname, part->partmap->name, part->number + 1); #endif grub_free (partname); diff --git a/grub-core/lib/i386/halt.c b/grub-core/lib/i386/halt.c index 15c4ba0d6..bd878c9bf 100644 --- a/grub-core/lib/i386/halt.c +++ b/grub-core/lib/i386/halt.c @@ -19,6 +19,7 @@ #include #include #include +#include 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 ... */ diff --git a/grub-core/lib/mips/arc/reboot.c b/grub-core/lib/mips/arc/reboot.c index f0d085765..ecf12a7ed 100644 --- a/grub-core/lib/mips/arc/reboot.c +++ b/grub-core/lib/mips/arc/reboot.c @@ -20,6 +20,7 @@ #include #include #include +#include void grub_reboot (void) @@ -28,7 +29,7 @@ grub_reboot (void) grub_millisleep (1500); - grub_printf ("Reboot failed\n"); + grub_puts_ (N_("Reboot failed")); grub_refresh (); while (1); } diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c index f099ba250..1b510784b 100644 --- a/grub-core/lib/mips/loongson/reboot.c +++ b/grub-core/lib/mips/loongson/reboot.c @@ -24,6 +24,7 @@ #include #include #include +#include void grub_reboot (void) @@ -51,7 +52,7 @@ grub_reboot (void) } grub_millisleep (1500); - grub_printf ("Reboot failed\n"); + grub_puts_ (N_("Reboot failed")); grub_refresh (); while (1); } diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index 8d6ec8f20..42fbdeb32 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -247,7 +247,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(chainloader) { cmd = grub_register_command ("chainloader", grub_cmd_chainloader, - "[--force|--bpb] FILE", + N_("[--force|--bpb] FILE"), N_("Load another boot loader.")); my_mod = mod; } diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index fa7af514b..36893ae62 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -1018,7 +1018,7 @@ grub_xnu_boot (void) { grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_printf ("Booting in blind mode\n"); + grub_puts_ (N_("Booting in blind mode")); bootparams->lfb_mode = 0; bootparams->lfb_width = 0; diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index d9e74b3c7..2de8e0909 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -182,7 +182,7 @@ grub_multiboot_set_console (int console_type, int accepted_consoles, if (console_required) return grub_error (GRUB_ERR_BAD_OS, "OS requires a console but none is available"); - grub_printf ("WARNING: no console will be available to OS"); + grub_puts_ (N_("WARNING: no console will be available to OS")); accepts_video = 0; accepts_ega_text = 0; return GRUB_ERR_NONE; diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 84bdc04d7..ba6a29020 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -520,10 +520,10 @@ void grub_bootp_init (void) { cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, - "[CARD]", + N_("[CARD]"), N_("perform a bootp autoconfiguration")); cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, - "[CARD]", + N_("[CARD]"), N_("perform a bootp autoconfiguration")); cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 0f8a60413..09acea900 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -946,16 +946,16 @@ static grub_command_t cmd_lsaddr; GRUB_MOD_INIT(net) { cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, - "SHORTNAME CARD ADDRESS [HWADDRESS]", + N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), N_("Add a network address.")); cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, - "SHORTNAME", + N_("SHORTNAME"), N_("Delete a network address.")); cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, - "SHORTNAME NET [INTERFACE| gw GATEWAY]", + N_("SHORTNAME NET [INTERFACE| gw GATEWAY]"), N_("Add a network route.")); cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, - "SHORTNAME", + N_("SHORTNAME"), N_("Delete a network route.")); cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes, "", N_("list network routes")); diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index a8b9e6683..922f8518f 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -24,6 +24,7 @@ #include #include #include +#include struct term_state { @@ -63,7 +64,9 @@ print_more (void) pos = grub_term_save_pos (); - grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str, + /* TRANSLATORS: This has to fit on one line. It's ok to include few + words but don't write poems. */ + grub_utf8_to_ucs4_alloc (_("--MORE--"), &unicode_str, &unicode_last_position); if (!unicode_str) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 888100aa2..490fbdd7b 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -24,6 +24,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -105,7 +106,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, /* disk->partition != NULL as 0 < delta */ partname = disk->partition ? grub_partition_get_name (disk->partition) : ""; - grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), disk->name, partname, p.partmap->name, p.number + 1); grub_free (partname); #endif diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c index ecaca140a..3377a2ccc 100644 --- a/grub-core/parttool/msdospart.c +++ b/grub-core/parttool/msdospart.c @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv2+"); @@ -35,7 +36,7 @@ static int type_table_handle = -1; static struct grub_parttool_argdesc grub_pcpart_bootargs[] = { - {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL}, + {"boot", N_("Make partition active"), GRUB_PARTTOOL_ARG_BOOL}, {0, 0, 0} }; @@ -65,12 +66,12 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, for (i = 0; i < 4; i++) mbr.entries[i].flag = 0x0; mbr.entries[index].flag = 0x80; - grub_printf ("Partition %d is active now. \n", index); + grub_printf_ (N_("Partition %d is active now. \n"), index); } else { mbr.entries[index].flag = 0x0; - grub_printf ("Cleared active flag on %d. \n", index); + grub_printf (N_("Cleared active flag on %d. \n"), index); } /* Write the MBR. */ @@ -83,8 +84,8 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, static struct grub_parttool_argdesc grub_pcpart_typeargs[] = { - {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL}, - {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL}, + {"type", N_("Change partition type"), GRUB_PARTTOOL_ARG_VAL}, + {"hidden", N_("Make partition hidden"), GRUB_PARTTOOL_ARG_BOOL}, {0, 0, 0} }; @@ -129,7 +130,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, } mbr.entries[index].type = type; - grub_printf ("Setting partition type to 0x%x\n", type); + grub_printf_ (N_("Setting partition type to 0x%x\n"), type); /* Write the parttable. */ grub_disk_write (dev->disk, part->offset, 0, diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 2f8deac18..a10af5930 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1111,7 +1111,10 @@ grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func) static const struct grub_arg_option background_image_cmd_options[] = { - {"mode", 'm', 0, "Background image mode.", "stretch|normal", + /* TRANSLATORS: note that GRUB will accept only original keywords stretch + and normal, not the translated ones. So please put both in translation + e.g. stretch=(%STRETCH%)|normal(=%NORMAL). */ + {"mode", 'm', 0, N_("Background image mode."), N_("stretch|normal"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 3419a5117..f8b29ec2e 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -606,7 +606,7 @@ print_terminfo (void) }; struct grub_term_output *cur; - grub_printf ("Current terminfo types: \n"); + grub_puts_ (N_("Current terminfo types:")); for (cur = terminfo_outputs; cur; cur = ((struct grub_terminfo_output_state *) cur->data)->next) grub_printf ("%s: %s\t%s\n", cur->name, diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 438ac92b2..92dd7ec07 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -993,15 +994,15 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, static void grub_video_vbe_print_adapter_specific_info (void) { - grub_printf (" VBE info: version: %d.%d OEM software rev: %d.%d\n", - controller_info.version >> 8, - controller_info.version & 0xFF, - controller_info.oem_software_rev >> 8, - controller_info.oem_software_rev & 0xFF); - + grub_printf_ (N_(" VBE info: version: %d.%d OEM software rev: %d.%d\n"), + controller_info.version >> 8, + controller_info.version & 0xFF, + controller_info.oem_software_rev >> 8, + controller_info.oem_software_rev & 0xFF); + /* The total_memory field is in 64 KiB units. */ - grub_printf (" total memory: %d KiB\n", - (controller_info.total_memory << 16) / 1024); + grub_printf_ (N_(" total memory: %d KiB\n"), + (controller_info.total_memory << 16) / 1024); } static struct grub_video_adapter grub_video_vbe_adapter = diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 513af47c1..aeabad976 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -24,6 +24,7 @@ #include #include #include +#include int main (int argc, char **argv) @@ -37,7 +38,7 @@ main (int argc, char **argv) if (argc >= 2 && argv[1][0] == '-') { - fprintf (stdout, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]); + fprintf (stdout, _("Usage: %s [INFILE [OUTFILE]]\n"), argv[0]); return 0; } @@ -46,7 +47,7 @@ main (int argc, char **argv) in = fopen (argv[1], "r"); if (!in) { - fprintf (stderr, "Couldn't open %s for reading: %s\n", + fprintf (stderr, _("Couldn't open %s for reading: %s\n"), argv[1], strerror (errno)); return 1; } @@ -61,7 +62,7 @@ main (int argc, char **argv) { if (in != stdin) fclose (in); - fprintf (stderr, "Couldn't open %s for writing: %s\n", + fprintf (stderr, _("Couldn't open %s for writing: %s\n"), argv[2], strerror (errno)); return 1; } diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index bdecae4a3..bdf8ef1c6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -62,7 +62,7 @@ make_device_map (const char *device_map, int floppy_disks) fp = fopen (device_map, "w"); if (! fp) - grub_util_error ("cannot open %s", device_map); + grub_util_error (_("cannot open %s"), device_map); grub_util_iterate_devices (process_device, floppy_disks); @@ -86,9 +86,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTION]...\n\ \n\ Generate a device map file automatically.\n\ @@ -101,7 +101,7 @@ Generate a device map file automatically.\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); exit (status); diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 04501cb40..8de07747d 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -260,9 +260,9 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS]\n\ -i, --input set input filename. Default is STDIN\n\ -o, --output set output filename. Default is STDOUT\n\ @@ -270,7 +270,7 @@ Usage: %s [OPTIONS]\n\ -V, --version print version information and exit.\n\ -v, --verbose print verbose messages.\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -300,7 +300,7 @@ lookup (char *code, int shift) if (strcmp (code, console_grub_equivalences_common[i].layout) == 0) return console_grub_equivalences_common[i].grub; - fprintf (stderr, "Unknown key %s\n", code); + fprintf (stderr, _("Unknown key %s\n"), code); return '\0'; } @@ -396,7 +396,7 @@ write_keymaps (FILE *in, FILE *out) if (keycode_usb == 0 || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - fprintf (stderr, "Unknown keycode 0x%02x\n", keycode_linux); + fprintf (stderr, _("Unknown keycode 0x%02x\n"), keycode_linux); continue; } if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) @@ -414,7 +414,7 @@ write_keymaps (FILE *in, FILE *out) if (ok == 0) { - fprintf (stderr, "ERROR: no keycodes found. Check output of %s.\n", + fprintf (stderr, _("ERROR: no keycodes found. Check output of %s.\n"), CKBCOMP); exit (1); } @@ -479,7 +479,7 @@ main (int argc, char *argv[]) in = stdin; if (!in) - grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); + grub_util_error (_("Couldn't open input file: %s\n"), strerror (errno)); if (outfile_name) out = fopen (outfile_name, "wb"); @@ -490,7 +490,7 @@ main (int argc, char *argv[]) { if (in != stdin) fclose (in); - grub_util_error ("Couldn't open output file: %s\n", strerror (errno)); + grub_util_error (_("Couldn't open output file: %s\n"), strerror (errno)); } write_keymaps (in, out); diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index 3fe3fe698..788db38a2 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -38,9 +38,9 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS] PATH\n\ \n\ Make a system path relative to its root.\n\ @@ -49,7 +49,7 @@ Options:\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -89,13 +89,13 @@ main (int argc, char *argv[]) if (optind >= argc) { - fprintf (stderr, "No path is specified.\n"); + fprintf (stderr, _("No path is specified.\n")); usage (1); } if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 2d1b31c9a..25358a553 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -51,9 +51,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try ``%s --help'' for more information.\n", program_name); + _("Try ``%s --help'' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [PATH]\n\ \n\ Checks GRUB script configuration file for syntax errors.\n\ @@ -63,7 +63,7 @@ Checks GRUB script configuration file for syntax errors.\n\ -v, --verbose print the script as it is being processed\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -157,7 +157,7 @@ main (int argc, char *argv[]) } else if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } else @@ -193,7 +193,7 @@ main (int argc, char *argv[]) if (found_input && script == 0) { - fprintf (stderr, "error: line no: %u\n", lineno); + fprintf (stderr, _("error: line no: %u\n"), lineno); return 1; } diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c index ee81457b3..03d47bc99 100644 --- a/util/ieee1275/grub-ofpathname.c +++ b/util/ieee1275/grub-ofpathname.c @@ -36,7 +36,7 @@ int main(int argc, char **argv) if (argc != 2 || strcmp (argv[1], "--help") == 0) { - printf("Usage: %s DEVICE\n", program_name); + printf(_("Usage: %s DEVICE\n"), program_name); return 1; } if (strcmp (argv[1], "--version") == 0) diff --git a/util/resolve.c b/util/resolve.c index 63bd7ccb2..3eb8bfb14 100644 --- a/util/resolve.c +++ b/util/resolve.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Module. */ struct mod_list @@ -87,7 +88,7 @@ read_dep_list (FILE *fp) /* Get the target name. */ p = strchr (buf, ':'); if (! p) - grub_util_error ("invalid line format: %s", buf); + grub_util_error (_("invalid line format: %s"), buf); *p++ = '\0'; @@ -240,7 +241,7 @@ grub_util_resolve_dependencies (const char *prefix, path = grub_util_get_path (prefix, dep_list_file); fp = fopen (path, "r"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); free (path); dep_list = read_dep_list (fp); From 119d11c8857ce2d354fbbada64cc27f783b57ecb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 22:35:09 +0100 Subject: [PATCH 207/315] Replace grub_fatal with normal errors in i386 linux loader. * grub-core/loader/i386/linux.c (find_efi_mmap_size): Return 0 on error. (allocate_pages): Check find_efi_mmap_size return value. (grub_e820_add_region): Return error. (grub_linux_boot): Check mmap return value. --- ChangeLog | 9 +++++++++ grub-core/loader/i386/linux.c | 38 ++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3c0cfe61..490bc693b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-11 Vladimir Serbinenko + + Replace grub_fatal with normal errors in i386 linux loader. + + * grub-core/loader/i386/linux.c (find_efi_mmap_size): Return 0 on error. + (allocate_pages): Check find_efi_mmap_size return value. + (grub_e820_add_region): Return error. + (grub_linux_boot): Check mmap return value. + 2011-11-11 Vladimir Serbinenko * grub-core/commands/acpihalt.c: Gettextized. diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index a6eb95028..c63c6c3ef 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -130,7 +130,10 @@ find_efi_mmap_size (void) grub_free (mmap); if (ret < 0) - grub_fatal ("cannot get memory map"); + { + grub_error (GRUB_ERR_IO, "cannot get memory map"); + return 0; + } else if (ret > 0) break; @@ -198,6 +201,8 @@ allocate_pages (grub_size_t prot_size) #ifdef GRUB_MACHINE_EFI efi_mmap_size = find_efi_mmap_size (); + if (efi_mmap_size == 0) + return grub_errno; #endif grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n", @@ -291,7 +296,7 @@ allocate_pages (grub_size_t prot_size) return err; } -static void +static grub_err_t grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, grub_uint64_t start, grub_uint64_t size, grub_uint32_t type) @@ -299,7 +304,10 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, int n = *e820_num; if (n >= GRUB_E820_MAX_ENTRY) - grub_fatal ("Too many e820 memory map entries"); + { + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Too many e820 memory map entries"); + } if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && (e820_map[n - 1].type == type)) @@ -311,6 +319,7 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, e820_map[n].type = type; (*e820_num)++; } + return GRUB_ERR_NONE; } static grub_err_t @@ -446,37 +455,38 @@ grub_linux_boot (void) int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type) { + grub_uint32_t e820_type; switch (type) { case GRUB_MEMORY_AVAILABLE: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_RAM); + e820_type = GRUB_E820_RAM; break; case GRUB_MEMORY_ACPI: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_ACPI); + e820_type = GRUB_E820_ACPI; break; case GRUB_MEMORY_NVS: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_NVS); + e820_type = GRUB_E820_NVS; break; case GRUB_MEMORY_BADRAM: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_BADRAM); + e820_type = GRUB_E820_BADRAM; break; default: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_RESERVED); + e820_type = GRUB_E820_RESERVED; } + if (grub_e820_add_region (params->e820_map, &e820_num, + addr, size, e820_type)) + return 1; + return 0; } e820_num = 0; - grub_mmap_iterate (hook); + if (grub_mmap_iterate (hook)) + return grub_errno; params->mmap_size = e820_num; modevar = grub_env_get ("gfxpayload"); From 566f779bd8a7245f5c867ab276d62a0b54d3c222 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 11 Nov 2011 22:58:18 +0100 Subject: [PATCH 208/315] 2011-11-11 Robert Millan * util/getroot.c (grub_util_get_geom_abstraction): Remove __attribute__((unused)) from `os_dev', which *is* being used. --- ChangeLog | 5 +++++ util/getroot.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 490bc693b..6b726987a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Robert Millan + + * util/getroot.c (grub_util_get_geom_abstraction): Remove + __attribute__((unused)) from `os_dev', which *is* being used. + 2011-11-11 Vladimir Serbinenko Replace grub_fatal with normal errors in i386 linux loader. diff --git a/util/getroot.c b/util/getroot.c index 41fbdec10..750773c90 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -826,7 +826,7 @@ grub_util_get_geom_abstraction (const char *dev) #endif int -grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) +grub_util_get_dev_abstraction (const char *os_dev) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* User explicitly claims that this drive is visible by BIOS. */ From b50787de091db9e94dc48fe68e3d79d5126d065d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:26:04 +0100 Subject: [PATCH 209/315] * include/grub/dl.h (GRUB_ARCH_DL_TRAMP_SIZE) [__ia64__]: Add back forgotten define. (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Redefine in terms of GRUB_IA64_DL_GOT_ALIGN. (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Redefine in terms of GRUB_IA64_DL_TRAMP_ALIGN. --- ChangeLog | 9 +++++++++ include/grub/dl.h | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b726987a..3970ec293 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,15 @@ * util/getroot.c (grub_util_get_geom_abstraction): Remove __attribute__((unused)) from `os_dev', which *is* being used. +2011-11-11 Vladimir Serbinenko + + * include/grub/dl.h (GRUB_ARCH_DL_TRAMP_SIZE) [__ia64__]: Add back + forgotten define. + (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Redefine in terms of + GRUB_IA64_DL_GOT_ALIGN. + (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Redefine in terms of + GRUB_IA64_DL_TRAMP_ALIGN. + 2011-11-11 Vladimir Serbinenko Replace grub_fatal with normal errors in i386 linux loader. diff --git a/include/grub/dl.h b/include/grub/dl.h index 886e966cc..d5f009829 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -178,8 +178,9 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #if defined (__ia64__) -#define GRUB_ARCH_DL_TRAMP_ALIGN 16 -#define GRUB_ARCH_DL_GOT_ALIGN 16 +#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN +#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN +#define GRUB_ARCH_DL_TRAMP_SIZE GRUB_IA64_DL_TRAMP_SIZE #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size #else void From 10f0117bf93a31cdf952a6379ab33a03e4920993 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:34:14 +0100 Subject: [PATCH 210/315] * grub-core/commands/efi/fixvideo.c: Gettextize. * grub-core/commands/hashsum.c: Likewise. * grub-core/commands/i386/cmostest.c: Likewise. * grub-core/commands/i386/pc/drivemap.c: Likewise. * grub-core/commands/i386/pc/lsapm.c: Likewise. * grub-core/commands/i386/pc/sendkey.c: Likewise. * grub-core/commands/lsmmap.c: Likewise. * grub-core/commands/menuentry.c: Likewise. * grub-core/commands/mips/loongson/lsspd.c: Likewise. * grub-core/commands/setpci.c: Likewise. * grub-core/loader/i386/bsd.c: Likewise. * grub-core/loader/i386/linux.c: Likewise. * util/getroot.c: Likewise. * util/grub-editenv.c: Likewise. * util/grub-fstest.c: Likewise. * util/grub-mkfont.c: Likewise. * util/grub-mkimage.c: Likewise. * util/grub-mkpasswd-pbkdf2.c: Likewise. * util/grub-pe2elf.c: Likewise. * util/grub-probe.c: Likewise. * util/grub-setup.c: Likewise. * util/ieee1275/ofpath.c: Likewise. * util/misc.c: Likewise. * util/raid.c: Likewise. --- ChangeLog | 27 +++++++++++ grub-core/commands/efi/fixvideo.c | 10 ++-- grub-core/commands/hashsum.c | 10 ++-- grub-core/commands/i386/cmostest.c | 9 ++-- grub-core/commands/i386/pc/drivemap.c | 4 +- grub-core/commands/i386/pc/lsapm.c | 32 ++++++------- grub-core/commands/i386/pc/sendkey.c | 39 ++++++++-------- grub-core/commands/lsmmap.c | 22 ++++----- grub-core/commands/menuentry.c | 8 ++-- grub-core/commands/mips/loongson/lsspd.c | 24 +++++----- grub-core/commands/setpci.c | 14 +++--- grub-core/loader/i386/bsd.c | 10 ++-- grub-core/loader/i386/linux.c | 28 ++++++------ util/getroot.c | 58 ++++++++++++------------ util/grub-editenv.c | 28 ++++++------ util/grub-fstest.c | 10 ++-- util/grub-mkfont.c | 57 +++++++++++------------ util/grub-mkimage.c | 22 ++++----- util/grub-mkpasswd-pbkdf2.c | 35 +++++++------- util/grub-pe2elf.c | 2 + util/grub-probe.c | 29 ++++++------ util/grub-setup.c | 29 ++++++------ util/ieee1275/ofpath.c | 20 ++++---- util/misc.c | 22 ++++----- util/raid.c | 13 +++--- 25 files changed, 302 insertions(+), 260 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3970ec293..23679917c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/efi/fixvideo.c: Gettextize. + * grub-core/commands/hashsum.c: Likewise. + * grub-core/commands/i386/cmostest.c: Likewise. + * grub-core/commands/i386/pc/drivemap.c: Likewise. + * grub-core/commands/i386/pc/lsapm.c: Likewise. + * grub-core/commands/i386/pc/sendkey.c: Likewise. + * grub-core/commands/lsmmap.c: Likewise. + * grub-core/commands/menuentry.c: Likewise. + * grub-core/commands/mips/loongson/lsspd.c: Likewise. + * grub-core/commands/setpci.c: Likewise. + * grub-core/loader/i386/bsd.c: Likewise. + * grub-core/loader/i386/linux.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-editenv.c: Likewise. + * util/grub-fstest.c: Likewise. + * util/grub-mkfont.c: Likewise. + * util/grub-mkimage.c: Likewise. + * util/grub-mkpasswd-pbkdf2.c: Likewise. + * util/grub-pe2elf.c: Likewise. + * util/grub-probe.c: Likewise. + * util/grub-setup.c: Likewise. + * util/ieee1275/ofpath.c: Likewise. + * util/misc.c: Likewise. + * util/raid.c: Likewise. + 2011-11-11 Robert Millan * util/getroot.c (grub_util_get_geom_abstraction): Remove diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c index c53e47d8a..a58c27916 100644 --- a/grub-core/commands/efi/fixvideo.c +++ b/grub-core/commands/efi/fixvideo.c @@ -56,24 +56,24 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_target_addr_t base; - grub_printf ("Found graphic card: %s\n", p->name); + grub_dprintf ("fixvideo", "Found graphic card: %s\n", p->name); addr += 8 + p->mmio_bar * 4; base = grub_pci_read (addr); if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) || (base & GRUB_PCI_ADDR_MEM_PREFETCH)) - grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar); + grub_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar); else { base &= GRUB_PCI_ADDR_MEM_MASK; base += p->mmio_reg; if (*((volatile grub_uint32_t *) base) != p->mmio_old) - grub_printf ("Old value don't match\n"); + grub_dprintf ("fixvideo", "Old value doesn't match\n"); else { *((volatile grub_uint32_t *) base) = 0; if (*((volatile grub_uint32_t *) base)) - grub_printf ("Set MMIO fails\n"); + grub_dprintf ("fixvideo", "Setting MMIO fails\n"); } } @@ -82,7 +82,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) p++; } - grub_printf ("Unknown graphic card: %x\n", pciid); + grub_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid); } return 0; diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 6825d4811..fb737c2f8 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -141,7 +141,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, grub_file_close (file); if (err) { - grub_printf ("%s: READ ERROR\n", p); + grub_printf_ (N_("%s: READ ERROR\n"), p); if (!keep) { grub_file_close (hashlist); @@ -155,7 +155,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, } if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0) { - grub_printf ("%s: HASH MISMATCH\n", p); + grub_printf_ (N_("%s: HASH MISMATCH\n"), p); if (!keep) { grub_file_close (hashlist); @@ -166,7 +166,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, mismatch++; continue; } - grub_printf ("%s: OK\n", p); + grub_printf_ (N_("%s: OK\n"), p); } if (mismatch || unread) return grub_error (GRUB_ERR_TEST_FAILURE, @@ -257,8 +257,8 @@ static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc; GRUB_MOD_INIT(hashsum) { cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, - "hashsum -h HASH [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", + N_("-h HASH [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), N_("Compute or check hash checksum."), options); cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0, diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index 6439159bd..6a4290155 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -20,6 +20,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -86,11 +87,11 @@ static grub_command_t cmd, cmd_clean; GRUB_MOD_INIT(cmostest) { cmd = grub_register_command ("cmostest", grub_cmd_cmostest, - "cmostest BYTE:BIT", - "Test bit at BYTE:BIT in CMOS."); + N_("BYTE:BIT"), + N_("Test bit at BYTE:BIT in CMOS.")); cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean, - "cmosclean BYTE:BIT", - "Clean bit at BYTE:BIT in CMOS."); + N_("BYTE:BIT"), + N_("Clean bit at BYTE:BIT in CMOS.")); } GRUB_MOD_FINI(cmostest) diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index 9a89f968c..4f752bed5 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -178,11 +178,11 @@ list_mappings (void) /* Show: list mappings. */ if (! map_head) { - grub_printf ("No drives have been remapped\n"); + grub_puts_ (N_("No drives have been remapped")); return GRUB_ERR_NONE; } - grub_printf ("OS disk #num ------> GRUB/BIOS device\n"); + grub_puts_ (N_("OS disk #num ------> GRUB/BIOS device")); drivemap_node_t *curnode = map_head; while (curnode) { diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c index 17bcfd6eb..45b43b242 100644 --- a/grub-core/commands/i386/pc/lsapm.c +++ b/grub-core/commands/i386/pc/lsapm.c @@ -74,27 +74,27 @@ grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)), if (!grub_apm_get_info (&info)) return grub_error (GRUB_ERR_IO, "no APM found"); - grub_printf ("Vesion %u.%u\n" - "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" - "16-bit CS = 0x%x, len = 0x%x\n" - "DS = 0x%x, len = 0x%x\n", - info.version >> 8, info.version & 0xff, - info.cseg, info.cseg_len, info.offset, - info.cseg_16, info.cseg_16_len, - info.dseg, info.dseg_len); + grub_printf_ (N_("Vesion %u.%u\n" + "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" + "16-bit CS = 0x%x, len = 0x%x\n" + "DS = 0x%x, len = 0x%x\n"), + info.version >> 8, info.version & 0xff, + info.cseg, info.cseg_len, info.offset, + info.cseg_16, info.cseg_16_len, + info.dseg, info.dseg_len); grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED - ? "16-bit protected interface supported\n" - : "16-bit protected interface unsupported\n"); + ? _("16-bit protected interface supported\n") + : _("16-bit protected interface unsupported\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED - ? "32-bit protected interface supported\n" - : "32-bit protected interface unsupported\n"); + ? _("32-bit protected interface supported\n") + : _("32-bit protected interface unsupported\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN - ? "CPU Idle slows down processor\n" - : "CPU Idle doesn't slow down processor\n"); + ? _("CPU Idle slows down processor\n") + : _("CPU Idle doesn't slow down processor\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED - ? "APM disabled\n" : "APM enabled\n"); + ? _("APM disabled\n") : _("APM enabled\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED - ? "APM disengaged\n" : "APM engaged\n"); + ? _("APM disengaged\n") : _("APM engaged\n")); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index a55d17bd0..83400c347 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv2+"); @@ -35,23 +36,23 @@ static int keylen = 0; static int noled = 0; static const struct grub_arg_option options[] = { - {"num", 'n', 0, "set numlock mode", "[on|off]", ARG_TYPE_STRING}, - {"caps", 'c', 0, "set capslock mode", "[on|off]", ARG_TYPE_STRING}, - {"scroll", 's', 0, "set scrolllock mode", "[on|off]", ARG_TYPE_STRING}, - {"insert", 0, 0, "set insert mode", "[on|off]", ARG_TYPE_STRING}, - {"pause", 0, 0, "set pause mode", "[on|off]", ARG_TYPE_STRING}, - {"left-shift", 0, 0, "press left shift", "[on|off]", ARG_TYPE_STRING}, - {"right-shift", 0, 0, "press right shift", "[on|off]", ARG_TYPE_STRING}, - {"sysrq", 0, 0, "press SysRq", "[on|off]", ARG_TYPE_STRING}, - {"numkey", 0, 0, "press NumLock key", "[on|off]", ARG_TYPE_STRING}, - {"capskey", 0, 0, "press CapsLock key", "[on|off]", ARG_TYPE_STRING}, - {"scrollkey", 0, 0, "press ScrollLock key", "[on|off]", ARG_TYPE_STRING}, - {"insertkey", 0, 0, "press Insert key", "[on|off]", ARG_TYPE_STRING}, - {"left-alt", 0, 0, "press left alt", "[on|off]", ARG_TYPE_STRING}, - {"right-alt", 0, 0, "press right alt", "[on|off]", ARG_TYPE_STRING}, - {"left-ctrl", 0, 0, "press left ctrl", "[on|off]", ARG_TYPE_STRING}, - {"right-ctrl", 0, 0, "press right ctrl", "[on|off]", ARG_TYPE_STRING}, - {"no-led", 0, 0, "don't update LED state", 0, 0}, + {"num", 'n', 0, N_("set numlock mode"), "[on|off]", ARG_TYPE_STRING}, + {"caps", 'c', 0, N_("set capslock mode"), "[on|off]", ARG_TYPE_STRING}, + {"scroll", 's', 0, N_("set scrolllock mode"), "[on|off]", ARG_TYPE_STRING}, + {"insert", 0, 0, N_("set insert mode"), "[on|off]", ARG_TYPE_STRING}, + {"pause", 0, 0, N_("set pause mode"), "[on|off]", ARG_TYPE_STRING}, + {"left-shift", 0, 0, N_("press left shift"), "[on|off]", ARG_TYPE_STRING}, + {"right-shift", 0, 0, N_("press right shift"), "[on|off]", ARG_TYPE_STRING}, + {"sysrq", 0, 0, N_("press SysRq"), "[on|off]", ARG_TYPE_STRING}, + {"numkey", 0, 0, N_("press NumLock key"), "[on|off]", ARG_TYPE_STRING}, + {"capskey", 0, 0, N_("press CapsLock key"), "[on|off]", ARG_TYPE_STRING}, + {"scrollkey", 0, 0, N_("press ScrollLock key"), "[on|off]", ARG_TYPE_STRING}, + {"insertkey", 0, 0, N_("press Insert key"), "[on|off]", ARG_TYPE_STRING}, + {"left-alt", 0, 0, N_("press left alt"), "[on|off]", ARG_TYPE_STRING}, + {"right-alt", 0, 0, N_("press right alt"), "[on|off]", ARG_TYPE_STRING}, + {"left-ctrl", 0, 0, N_("press left ctrl"), "[on|off]", ARG_TYPE_STRING}, + {"right-ctrl", 0, 0, N_("press right ctrl"), "[on|off]", ARG_TYPE_STRING}, + {"no-led", 0, 0, N_("don't update LED state"), 0, 0}, {0, 0, 0, 0, 0, 0} }; static int simple_flag_offsets[] @@ -369,8 +370,8 @@ static void *preboot_hook; GRUB_MOD_INIT (sendkey) { cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0, - "sendkey [KEYSTROKE1] [KEYSTROKE2] ...", - "Emulate a keystroke", options); + N_("[KEYSTROKE1] [KEYSTROKE2] ..."), + N_("Emulate a keystroke"), options); preboot_hook = grub_loader_register_preboot_hook (grub_sendkey_preboot, diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c index 44598f0df..4815fd174 100644 --- a/grub-core/commands/lsmmap.c +++ b/grub-core/commands/lsmmap.c @@ -26,13 +26,13 @@ GRUB_MOD_LICENSE ("GPLv3+"); static const char *names[] = { - [GRUB_MEMORY_AVAILABLE] = "available", - [GRUB_MEMORY_RESERVED] = "reserved", - [GRUB_MEMORY_ACPI] = "ACPI reclamaible", - [GRUB_MEMORY_NVS] = "NVS", - [GRUB_MEMORY_BADRAM] = "BadRAM", - [GRUB_MEMORY_CODE] = "firmware code", - [GRUB_MEMORY_HOLE] = "hole" + [GRUB_MEMORY_AVAILABLE] = N_("available"), + [GRUB_MEMORY_RESERVED] = N_("reserved"), + [GRUB_MEMORY_ACPI] = N_("ACPI reclamaible"), + [GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage"), + [GRUB_MEMORY_BADRAM] = N_("BadRAM"), + [GRUB_MEMORY_CODE] = N_("firmware code"), + [GRUB_MEMORY_HOLE] = N_("hole") }; static grub_err_t @@ -46,11 +46,11 @@ grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), grub_memory_type_t type) { if (type < ARRAY_SIZE (names) && names[type]) - grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n", - (long long) addr, (long long) size, names[type]); + grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"), + (long long) addr, (long long) size, _(names[type])); else - grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", - (long long) addr, (long long) size, type); + grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"), + (long long) addr, (long long) size, type); return 0; } #ifndef GRUB_MACHINE_EMU diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 4849f8bb8..f5ec60bff 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -28,13 +28,13 @@ static const struct grub_arg_option options[] = { {"class", 1, GRUB_ARG_OPTION_REPEATABLE, - N_("Menu entry type."), "STRING", ARG_TYPE_STRING}, + N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, {"users", 2, 0, - N_("Users allowed to boot this entry."), "USERNAME", ARG_TYPE_STRING}, + N_("Users allowed to boot this entry."), N_("USERNAME"), ARG_TYPE_STRING}, {"hotkey", 3, 0, - N_("Keyboard key for this entry."), "KEY", ARG_TYPE_STRING}, + N_("Keyboard key for this entry."), N_("KEY"), ARG_TYPE_STRING}, {"source", 4, 0, - N_("Menu entry definition as a string."), "STRING", ARG_TYPE_STRING}, + N_("Menu entry definition as a string."), N_("STRING"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/commands/mips/loongson/lsspd.c b/grub-core/commands/mips/loongson/lsspd.c index c1c5e2ef7..76999368f 100644 --- a/grub-core/commands/mips/loongson/lsspd.c +++ b/grub-core/commands/mips/loongson/lsspd.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -38,43 +39,44 @@ grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), if (!grub_cs5536_find (&dev)) { - grub_printf ("No CS5536 found\n"); + grub_puts_ (N_("No CS5536 found")); return GRUB_ERR_NONE; } - grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev), - grub_pci_get_device (dev), grub_pci_get_function (dev)); + grub_printf_ (N_("CS5536 at %d:%d.%d\n"), grub_pci_get_bus (dev), + grub_pci_get_device (dev), grub_pci_get_function (dev)); err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase); if (err) return err; - grub_printf ("SMB base = 0x%x\n", smbbase); + grub_printf_ (N_("SMB base = 0x%x\n"), smbbase); for (i = GRUB_SMB_RAM_START_ADDR; i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++) { struct grub_smbus_spd spd; grub_memset (&spd, 0, sizeof (spd)); - grub_printf ("Device %d\n", i); + grub_printf_ (N_("Device %d\n"), i); err = grub_cs5536_read_spd (smbbase, i, &spd); if (err) { grub_print_error (); continue; } - grub_printf ("Written SPD bytes: %d B.\n", spd.written_size); - grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size); + grub_printf_ (N_("Written SPD bytes: %d B.\n"), spd.written_size); + grub_printf_ (N_("Total flash size: %d B.\n"), + 1 << spd.log_total_flash_size); if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2) { char str[sizeof (spd.ddr2.part_number) + 1]; - grub_printf ("Memory type: DDR2.\n"); + grub_puts_ (N_("Memory type: DDR2.")); grub_memcpy (str, spd.ddr2.part_number, sizeof (spd.ddr2.part_number)); str[sizeof (spd.ddr2.part_number)] = 0; - grub_printf ("Part no: %s.\n", str); + grub_printf_ (N_("Part no: %s.\n"), str); } else - grub_printf ("Memory type: Unknown.\n"); + grub_puts_ (N_("Memory type: Unknown.")); } return GRUB_ERR_NONE; @@ -85,7 +87,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(lsspd) { cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0, - "Print Memory information."); + N_("Print Memory information.")); } GRUB_MOD_FINI(lsspd) diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index 70f5bcdad..81e7f726d 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -66,12 +66,12 @@ static struct pci_register pci_registers[] = static const struct grub_arg_option options[] = { - {0, 'd', 0, "Select device by vendor and device IDs.", - "[vendor]:[device]", ARG_TYPE_STRING}, - {0, 's', 0, "Select device by its position on the bus.", - "[bus]:[slot][.func]", ARG_TYPE_STRING}, - {0, 'v', 0, "Save read value into variable VARNAME.", - "VARNAME", ARG_TYPE_STRING}, + {0, 'd', 0, N_("Select device by vendor and device IDs."), + N_("[vendor]:[device]"), ARG_TYPE_STRING}, + {0, 's', 0, N_("Select device by its position on the bus."), + N_("[bus]:[slot][.func]"), ARG_TYPE_STRING}, + {0, 'v', 0, N_("Save read value into variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -128,7 +128,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (!write_mask) { - grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr, + grub_printf (N_("Register %x of %d:%d.%d is %x\n"), regaddr, grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index f2d0845f8..6746b3853 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -450,7 +450,8 @@ grub_freebsd_list_modules (void) { struct bsd_tag *tag; - grub_printf (" %-18s %-18s%14s%14s\n", "name", "type", "addr", "size"); + grub_printf (" %-18s %-18s%14s%14s\n", _("name"), _("type"), _("addr"), + _("size")); for (tag = tags; tag; tag = tag->next) { @@ -515,7 +516,8 @@ grub_netbsd_list_modules (void) { struct netbsd_module *mod; - grub_printf (" %-18s%14s%14s%14s\n", "name", "type", "addr", "size"); + grub_printf (" %-18s%14s%14s%14s\n", _("name"), _("type"), _("addr"), + _("size")); for (mod = netbsd_mods; mod; mod = mod->next) grub_printf (" %-18s 0x%08x 0x%08x 0x%08x", mod->mod.name, @@ -1050,7 +1052,7 @@ grub_netbsd_boot (void) if (err) { grub_print_error (); - grub_printf ("Booting however\n"); + grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } @@ -2061,7 +2063,7 @@ GRUB_MOD_INIT (bsd) cmd_openbsd_ramdisk = grub_register_command ("kopenbsd_ramdisk", grub_cmd_openbsd_ramdisk, 0, - "Load kOpenBSD ramdisk. "); + N_("Load kOpenBSD ramdisk.")); my_mod = mod; } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index c63c6c3ef..80ad542e3 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -517,7 +517,7 @@ grub_linux_boot (void) if (err) { grub_print_error (); - grub_printf ("Booting however\n"); + grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } @@ -793,7 +793,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), vid_mode = GRUB_LINUX_VID_MODE_EXTENDED; else if (grub_strcmp (val, "ask") == 0) { - grub_printf ("Legacy `ask' parameter no longer supported.\n"); + grub_puts_ (N_("Legacy `ask' parameter no longer supported.")); /* We usually would never do this in a loader, but "vga=ask" means user requested interaction, so it can't hurt to request keyboard input. */ @@ -809,9 +809,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), case 0: case GRUB_LINUX_VID_MODE_NORMAL: grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. " - "Use set gfxpayload=text before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=text before " + "linux command instead.\n"), argv[i]); break; @@ -819,9 +819,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), case GRUB_LINUX_VID_MODE_EXTENDED: /* FIXME: support 80x50 text. */ grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. " - "Use set gfxpayload=text before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=text before " + "linux command instead.\n"), argv[i]); break; default: @@ -830,9 +830,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), vid_mode > GRUB_VESA_MODE_TABLE_END) { grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. Mode %d isn't recognized. " - "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. Mode %d isn't recognized. " + "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] " + "before linux command instead.\n"), argv[i], vid_mode); break; } @@ -847,9 +847,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! buf) goto fail; - grub_printf ("%s is deprecated. " - "Use set gfxpayload=%s before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), argv[i], buf); err = grub_env_set ("gfxpayload", buf); grub_free (buf); diff --git a/util/getroot.c b/util/getroot.c index 750773c90..f5d6d3f62 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef HAVE_DEVICE_MAPPER # include @@ -454,7 +455,7 @@ grub_find_device (const char *dir, dev_t dev) continue; if (chdir (saved_cwd) < 0) - grub_util_error ("cannot restore the original directory"); + grub_util_error (_("cannot restore the original directory")); free (saved_cwd); closedir (dp); @@ -463,7 +464,7 @@ grub_find_device (const char *dir, dev_t dev) } if (chdir (saved_cwd) < 0) - grub_util_error ("cannot restore the original directory"); + grub_util_error (_("cannot restore the original directory")); free (saved_cwd); closedir (dp); @@ -581,17 +582,17 @@ grub_guess_root_device (const char *dir) &data, &data_len); if (num_ints < 1) - grub_util_error ("Storage info for `%s' does not include type", dir); + grub_util_error (_("Storage info for `%s' does not include type"), dir); if (ints[0] != STORAGE_DEVICE) - grub_util_error ("Filesystem of `%s' is not stored on local disk", dir); + grub_util_error (_("Filesystem of `%s' is not stored on local disk"), dir); if (num_ints < 5) - grub_util_error ("Storage info for `%s' does not include name", dir); + grub_util_error (_("Storage info for `%s' does not include name"), dir); name_len = ints[4]; if (name_len < data_len) - grub_util_error ("Bogus name length for storage info for `%s'", dir); + grub_util_error (_("Bogus name length for storage info for `%s'"), dir); if (data[name_len - 1] != '\0') - grub_util_error ("Storage name for `%s' not NUL-terminated", dir); + grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir); os_dev = xmalloc (strlen ("/dev/") + data_len); memcpy (os_dev, "/dev/", strlen ("/dev/")); @@ -653,7 +654,7 @@ grub_guess_root_device (const char *dir) } if (stat (dir, &st) < 0) - grub_util_error ("cannot stat `%s'", dir); + grub_util_error (_("cannot stat `%s'"), dir); dev = st.st_dev; @@ -692,7 +693,7 @@ grub_util_open_dm (const char *os_dev, struct dm_tree **tree, *tree = dm_tree_create (); if (! *tree) { - grub_printf ("Failed to create tree\n"); + grub_puts_ (N_("Failed to create tree")); grub_dprintf ("hostdisk", "dm_tree_create failed\n"); return 0; } @@ -808,7 +809,7 @@ grub_util_get_geom_abstraction (const char *dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -874,13 +875,14 @@ get_mdadm_uuid (const char *os_dev) if (pipe (mdadm_pipe) < 0) { - grub_util_warn ("Unable to create pipe for mdadm: %s", strerror (errno)); + grub_util_warn (_("Unable to create pipe for mdadm: %s"), + strerror (errno)); return NULL; } mdadm_pid = fork (); if (mdadm_pid < 0) - grub_util_warn ("Unable to fork mdadm: %s", strerror (errno)); + grub_util_warn (_("Unable to fork mdadm: %s"), strerror (errno)); else if (mdadm_pid == 0) { /* Child. */ @@ -911,7 +913,7 @@ get_mdadm_uuid (const char *os_dev) mdadm = fdopen (mdadm_pipe[0], "r"); if (! mdadm) { - grub_util_warn ("Unable to open stream from mdadm: %s", + grub_util_warn (_("Unable to open stream from mdadm: %s"), strerror (errno)); goto out; } @@ -971,7 +973,7 @@ grub_util_pull_device (const char *os_dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -989,7 +991,7 @@ grub_util_pull_device (const char *os_dev) LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) break; if (!consumer) - grub_util_error ("couldn't find geli consumer"); + grub_util_error (_("couldn't find geli consumer")); fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); grub_util_info ("consumer %s", consumer->lg_provider->lg_name); lastsubdev = consumer->lg_provider->lg_name; @@ -1009,7 +1011,7 @@ grub_util_pull_device (const char *os_dev) grub_err_t err; err = grub_cryptodisk_cheat_mount (grdev, os_dev); if (err) - grub_util_error ("Can't mount crypto: %s", grub_errmsg); + grub_util_error (_("Can't mount crypto: %s"), _(grub_errmsg)); } grub_free (grdev); @@ -1053,7 +1055,7 @@ grub_util_pull_device (const char *os_dev) grub_err_t err; err = grub_cryptodisk_cheat_mount (grdev, os_dev); if (err) - grub_util_error ("Can't mount crypto: %s", grub_errmsg); + grub_util_error (_("Can't mount crypto: %s"), _(grub_errmsg)); } grub_free (grdev); } @@ -1141,7 +1143,7 @@ grub_util_get_grub_dev (const char *os_dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -1159,11 +1161,11 @@ grub_util_get_grub_dev (const char *os_dev) LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) break; if (!consumer) - grub_util_error ("couldn't find geli consumer"); + grub_util_error (_("couldn't find geli consumer")); fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); uuid = grub_util_get_geli_uuid (fname); if (!uuid) - grub_util_error ("couldn't retrieve geli UUID"); + grub_util_error (_("couldn't retrieve geli UUID")); grub_dev = xasprintf ("cryptouuid/%s", uuid); free (fname); free (uuid); @@ -1248,7 +1250,7 @@ grub_util_get_grub_dev (const char *os_dev) free (p); } else - grub_util_error ("unknown kind of RAID device `%s'", os_dev); + grub_util_error (_("unknown kind of RAID device `%s'"), os_dev); { char *mdadm_name = get_mdadm_uuid (os_dev); @@ -1290,7 +1292,7 @@ grub_util_check_block_device (const char *blk_dev) struct stat st; if (stat (blk_dev, &st) < 0) - grub_util_error ("cannot stat `%s'", blk_dev); + grub_util_error (_("cannot stat `%s'"), blk_dev); if (S_ISBLK (st.st_mode)) return (blk_dev); @@ -1304,7 +1306,7 @@ grub_util_check_char_device (const char *blk_dev) struct stat st; if (stat (blk_dev, &st) < 0) - grub_util_error ("cannot stat `%s'", blk_dev); + grub_util_error (_("cannot stat `%s'"), blk_dev); if (S_ISCHR (st.st_mode)) return (blk_dev); @@ -1320,7 +1322,7 @@ get_win32_path (const char *path) { char winpath[PATH_MAX]; if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) - grub_util_error ("cygwin_conv_path() failed"); + grub_util_error (_("cygwin_conv_path() failed")); int len = strlen (winpath); int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); @@ -1438,7 +1440,7 @@ grub_make_system_path_relative_to_its_root (const char *path) /* canonicalize. */ p = canonicalize_file_name (path); if (p == NULL) - grub_util_error ("failed to get canonical path of %s", path); + grub_util_error (_("failed to get canonical path of %s"), path); #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ @@ -1453,7 +1455,7 @@ grub_make_system_path_relative_to_its_root (const char *path) free (p); if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + grub_util_error (_("cannot stat %s: %s"), buf, strerror (errno)); buf2 = xstrdup (buf); num = st.st_dev; @@ -1465,14 +1467,14 @@ grub_make_system_path_relative_to_its_root (const char *path) p = strrchr (buf, '/'); if (p == NULL) /* This should never happen. */ - grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); + grub_util_error (_("FIXME: no / in buf. (make_system_path_relative_to_its_root)")); if (p != buf) *p = 0; else *++p = 0; if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + grub_util_error (_("cannot stat %s: %s"), buf, strerror (errno)); /* buf is another filesystem; we found it. */ if (st.st_dev != num) diff --git a/util/grub-editenv.c b/util/grub-editenv.c index 519945411..2bff80612 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -115,26 +115,26 @@ create_envblk_file (const char *name) buf = malloc (DEFAULT_ENVBLK_SIZE); if (! buf) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); namenew = xasprintf ("%s.new", name); fp = fopen (namenew, "wb"); if (! fp) - grub_util_error ("cannot open the file %s", namenew); + grub_util_error (_("cannot open the file %s"), namenew); memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE) - grub_util_error ("cannot write to the file %s", namenew); + grub_util_error (_("cannot write to the file %s"), namenew); fsync (fileno (fp)); free (buf); fclose (fp); if (rename (namenew, name) < 0) - grub_util_error ("cannot rename the file %s to %s", namenew, name); + grub_util_error (_("cannot rename the file %s to %s"), namenew, name); free (namenew); } @@ -153,29 +153,29 @@ open_envblk_file (const char *name) create_envblk_file (name); fp = fopen (name, "rb"); if (! fp) - grub_util_error ("cannot open the file %s", name); + grub_util_error (_("cannot open the file %s"), name); } if (fseek (fp, 0, SEEK_END) < 0) - grub_util_error ("cannot seek the file %s", name); + grub_util_error (_("cannot seek the file %s"), name); size = (size_t) ftell (fp); if (fseek (fp, 0, SEEK_SET) < 0) - grub_util_error ("cannot seek the file %s", name); + grub_util_error (_("cannot seek the file %s"), name); buf = malloc (size); if (! buf) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); if (fread (buf, 1, size, fp) != size) - grub_util_error ("cannot read the file %s", name); + grub_util_error (_("cannot read the file %s"), name); fclose (fp); envblk = grub_envblk_open (buf, size); if (! envblk) - grub_util_error ("invalid environment block"); + grub_util_error (_("invalid environment block")); return envblk; } @@ -204,11 +204,11 @@ write_envblk (const char *name, grub_envblk_t envblk) fp = fopen (name, "wb"); if (! fp) - grub_util_error ("cannot open the file %s", name); + grub_util_error (_("cannot open the file %s"), name); if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp) != grub_envblk_size (envblk)) - grub_util_error ("cannot write to the file %s", name); + grub_util_error (_("cannot write to the file %s"), name); fsync (fileno (fp)); fclose (fp); @@ -226,12 +226,12 @@ set_variables (const char *name, int argc, char *argv[]) p = strchr (argv[0], '='); if (! p) - grub_util_error ("invalid parameter %s", argv[0]); + grub_util_error (_("invalid parameter %s"), argv[0]); *(p++) = 0; if (! grub_envblk_set (envblk, argv[0], p)) - grub_util_error ("environment block too small"); + grub_util_error (_("environment block too small")); argc--; argv++; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 47b536771..c9f24ff08 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -395,11 +395,11 @@ fstest (int n, char **args) if (!fs) grub_util_error (grub_errmsg); if (!fs->uuid) - grub_util_error ("couldn't retrieve UUID"); + grub_util_error (_("couldn't retrieve UUID")); if (fs->uuid (dev, &uuid)) grub_util_error (grub_errmsg); if (!uuid) - grub_util_error ("couldn't retrieve UUID"); + grub_util_error (_("couldn't retrieve UUID")); argv[1] = uuid; execute_command ("xnu_uuid", 2, argv); grub_free (uuid); @@ -470,7 +470,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (strcmp (arg, "prompt") == 0) { char buf[1024]; - grub_printf ("Enter ZFS password: "); + grub_puts_ (N_("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); @@ -484,13 +484,13 @@ argp_parser (int key, char *arg, struct argp_state *state) f = fopen (arg, "rb"); if (!f) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); return 0; } real_size = fread (buf, 1, 1024, f); if (real_size < 0) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); fclose (f); return 0; } diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 3108d4694..1fad15660 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -121,9 +121,10 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS] FONT_FILES\n\ \nOptions:\n\ -o, --output=FILE_NAME set output file name\n\ @@ -143,7 +144,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -188,12 +189,12 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, err = FT_Load_Glyph (face, glyph_idx, flag); if (err) { - printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s", + printf (_("Freetype Error %d loading glyph 0x%x for U+0x%x%s"), err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK, char_code & GRUB_FONT_CODE_RIGHT_JOINED - ? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)": - " (leftmost)") - : ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)": + ? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? _(" (medial)"): + _(" (leftmost)")) + : ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? _(" (rightmost)"): "")); if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) @@ -519,7 +520,7 @@ process_cursive (struct gsub_feature *feature, if (substtype == GSUB_SUBSTITUTION_DELTA) add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target); else if (i >= grub_be_to_cpu16 (sub->count)) - printf ("Out of range substitution (%d, %d)\n", i, + printf (_("Out of range substitution (%d, %d)\n"), i, grub_be_to_cpu16 (sub->count)); else add_subst (glyph, grub_be_to_cpu16 (sub->repl[i++]), target); @@ -531,7 +532,7 @@ process_cursive (struct gsub_feature *feature, struct gsub_lookup *lookup; if (lookup_index >= grub_be_to_cpu16 (lookups->count)) { - printf ("Out of range lookup: %d\n", lookup_index); + printf (_("Out of range lookup: %d\n"), lookup_index); continue; } lookup = (struct gsub_lookup *) @@ -539,13 +540,13 @@ process_cursive (struct gsub_feature *feature, + grub_be_to_cpu16 (lookups->offsets[lookup_index])); if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION) { - printf ("Unsupported substitution type: %d\n", + printf (_("Unsupported substitution type: %d\n"), grub_be_to_cpu16 (lookup->type)); continue; } if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR) { - printf ("Unsupported substitution flag: 0x%x\n", + printf (_("Unsupported substitution flag: 0x%x\n"), grub_be_to_cpu16 (lookup->flag)); } switch (feattag) @@ -575,7 +576,7 @@ process_cursive (struct gsub_feature *feature, if (substtype != GSUB_SUBSTITUTION_MAP && substtype != GSUB_SUBSTITUTION_DELTA) { - printf ("Unsupported substitution specification: %d\n", + printf (_("Unsupported substitution specification: %d\n"), substtype); continue; } @@ -601,7 +602,7 @@ process_cursive (struct gsub_feature *feature, subst (m); } else - printf ("Unsupported coverage specification: %d\n", covertype); + printf (_("Unsupported coverage specification: %d\n"), covertype); } } } @@ -640,7 +641,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) grub_uint32_t feattag = grub_be_to_cpu32 (features->features[i].feature_tag); if (feature->params) - printf ("WARNING: unsupported feature parameters: %x\n", + printf (_("WARNING: unsupported feature parameters: %x\n"), grub_be_to_cpu16 (feature->params)); switch (feattag) { @@ -670,7 +671,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) for (j = 0; j < 4; j++) if (!grub_isgraph (str[j])) str[j] = '?'; - printf ("Unknown gsub feature 0x%x (%s)\n", feattag, str); + printf (_("Unknown gsub feature 0x%x (%s)\n"), feattag, str); } } } @@ -739,8 +740,8 @@ print_glyphs (struct grub_font_info *font_info) int x, y, xmax, xmin, ymax, ymin; grub_uint8_t *bitmap, mask; - printf ("\nGlyph #%d, U+%04x\n", num, glyph->char_code); - printf ("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n", + printf (_("\nGlyph #%d, U+%04x\n"), num, glyph->char_code); + printf (_("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n"), glyph->width, glyph->height, glyph->x_ofs, glyph->y_ofs, glyph->device_width); @@ -807,7 +808,7 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("Can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); int correct_size; for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs; @@ -843,7 +844,7 @@ write_font_width_spec (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("Can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); for (glyph = font_info->glyphs_sorted; glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++) @@ -866,7 +867,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); offset = 0; @@ -1063,7 +1064,7 @@ main (int argc, char *argv[]) a = strtoul (p, &p, 0); if (*p != '-') - grub_util_error ("invalid font range"); + grub_util_error (_("invalid font range")); b = strtoul (p + 1, &p, 0); if ((font_info.num_range & (GRUB_FONT_RANGE_BLOCK - 1)) == 0) font_info.ranges = xrealloc (font_info.ranges, @@ -1078,7 +1079,7 @@ main (int argc, char *argv[]) if (*p) { if (*p != ',') - grub_util_error ("invalid font range"); + grub_util_error (_("invalid font range")); else p++; } @@ -1124,7 +1125,7 @@ main (int argc, char *argv[]) if (file_format == ASCII_BITMAPS && font_info.num_range > 0) { - grub_util_error ("Option --ascii-bitmaps doesn't accept ranges (use ASCII)."); + grub_util_error (_("Option --ascii-bitmaps doesn't accept ranges (use ASCII).")); return 1; } @@ -1140,10 +1141,10 @@ main (int argc, char *argv[]) } if (! output_file) - grub_util_error ("no output file is specified"); + grub_util_error (_("no output file is specified")); if (FT_Init_FreeType (&ft_lib)) - grub_util_error ("FT_Init_FreeType fails"); + grub_util_error (_("FT_Init_FreeType fails")); for (; optind < argc; optind++) { @@ -1154,8 +1155,8 @@ main (int argc, char *argv[]) err = FT_New_Face (ft_lib, argv[optind], font_index, &ft_face); if (err) { - grub_printf ("can't open file %s, index %d: error %d", argv[optind], - font_index, err); + grub_printf (_("can't open file %s, index %d: error %d"), + argv[optind], font_index, err); if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) printf (": %s\n", ft_errmsgs[err]); else @@ -1181,7 +1182,7 @@ main (int argc, char *argv[]) font_info.size = size; if (FT_Set_Pixel_Sizes (ft_face, size, size)) - grub_util_error ("can't set %dx%d font size", size, size); + grub_util_error (_("can't set %dx%d font size"), size, size); add_font (&font_info, ft_face, file_format != PF2); FT_Done_Face (ft_face); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index fb1c5babe..9369fba3d 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -703,7 +703,7 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS && (comp != COMPRESSION_NONE)) - grub_util_error ("unknown compression %d\n", comp); + grub_util_error (_("unknown compression %d\n"), comp); *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); @@ -945,7 +945,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], name = "none_decompress.img"; break; default: - grub_util_error ("unknown compression %d\n", comp); + grub_util_error (_("unknown compression %d\n"), comp); } decompress_path = grub_util_get_path (dir, name); @@ -1301,7 +1301,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], boot_path = grub_util_get_path (dir, "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); + grub_util_error (_("diskboot.img is not one sector size")); boot_img = grub_util_read_image (boot_path); @@ -1366,11 +1366,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_MD_SHA512->final (context); if (grub_memcmp (GRUB_MD_SHA512->read (context), fwstart_good_hash, GRUB_MD_SHA512->mdlen) != 0) - grub_util_warn ("fwstart.img doesn't match the known good version. " - "Proceed at your own risk"); + grub_util_warn (_("fwstart.img doesn't match the known good version. " + "proceed at your own risk")); if (core_size + boot_size > 512 * 1024) - grub_util_error ("firmware image is too big"); + grub_util_error (_("firmware image is too big")); rom_size = 512 * 1024; rom_img = xmalloc (rom_size); @@ -1394,7 +1394,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t rom_size; if (core_size > 512 * 1024) - grub_util_error ("firmware image is too big"); + grub_util_error (_("firmware image is too big")); rom_size = 512 * 1024; rom_img = xmalloc (rom_size); @@ -1762,7 +1762,7 @@ main (int argc, char *argv[]) image_target = &image_targets[i]; if (!image_target) { - printf ("unknown target format %s\n", optarg); + printf (_("unknown target format %s\n"), optarg); usage (1); } break; @@ -1803,14 +1803,14 @@ main (int argc, char *argv[]) #ifdef HAVE_LIBLZMA comp = COMPRESSION_XZ; #else - grub_util_error ("grub-mkimage is compiled without XZ support", + grub_util_error (_("grub-mkimage is compiled without XZ support"), optarg); #endif } else if (grub_strcmp (optarg, "none") == 0) comp = COMPRESSION_NONE; else - grub_util_error ("Unknown compression format %s", optarg); + grub_util_error (_("Unknown compression format %s"), optarg); break; case 'h': @@ -1840,7 +1840,7 @@ main (int argc, char *argv[]) if (!image_target) { - printf ("Target format not specified (use the -O option).\n"); + printf (_("Target format not specified (use the -O option).\n")); usage (1); } diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index f75f27611..9c676a100 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -46,16 +46,17 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS]\n\ \nOptions:\n\ -c number, --iteration-count=number Number of PBKDF2 iterations\n\ -l number, --buflen=number Length of generated hash\n\ -s number, --salt=number Length of salt\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -135,12 +136,12 @@ main (int argc, char *argv[]) bufhex = malloc (buflen * 2 + 1); if (!bufhex) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); buf = malloc (buflen); if (!buf) { free (bufhex); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } salt = malloc (saltlen); @@ -148,7 +149,7 @@ main (int argc, char *argv[]) { free (bufhex); free (buf); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } salthex = malloc (saltlen * 2 + 1); if (!salthex) @@ -156,26 +157,26 @@ main (int argc, char *argv[]) free (salt); free (bufhex); free (buf); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } - printf ("Enter password: "); + printf ("%s", _("Enter password: ")); if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN)) { free (buf); free (bufhex); free (salthex); free (salt); - grub_util_error ("failure to read password"); + grub_util_error (_("failure to read password")); } - printf ("\nReenter password: "); + printf ("\n%s", _("Reenter password: ")); if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN)) { free (buf); free (bufhex); free (salthex); free (salt); - grub_util_error ("failure to read password"); + grub_util_error (_("failure to read password")); } if (strcmp (pass1, pass2) != 0) @@ -186,12 +187,12 @@ main (int argc, char *argv[]) free (bufhex); free (salthex); free (salt); - grub_util_error ("passwords don't match"); + grub_util_error (_("passwords don't match")); } memset (pass2, 0, sizeof (pass2)); #if ! defined (__linux__) && ! defined (__FreeBSD__) - printf ("WARNING: your random generator isn't known to be secure\n"); + printf ("%s", _("WARNING: your random generator isn't known to be secure\n")); #endif { @@ -206,7 +207,7 @@ main (int argc, char *argv[]) free (salthex); free (salt); fclose (f); - grub_util_error ("couldn't retrieve random data for salt"); + grub_util_error (_("couldn't retrieve random data for salt")); } rd = fread (salt, 1, saltlen, f); if (rd != saltlen) @@ -217,7 +218,7 @@ main (int argc, char *argv[]) free (bufhex); free (salthex); free (salt); - grub_util_error ("couldn't retrieve random data for salt"); + grub_util_error (_("couldn't retrieve random data for salt")); } fclose (f); } @@ -238,13 +239,13 @@ main (int argc, char *argv[]) memset (salthex, 0, 2 * saltlen); free (salt); free (salthex); - grub_util_error ("cryptographic error number %d", gcry_err); + grub_util_error (_("cryptographic error number %d"), gcry_err); } hexify (bufhex, buf, buflen); hexify (salthex, salt, saltlen); - printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", + printf (_("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n"), count, salthex, bufhex); memset (buf, 0, buflen); memset (bufhex, 0, 2 * buflen); diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index 4b93faa05..51d41c9f0 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -31,6 +31,8 @@ #include "progname.h" +/* Please don't internationalise this file. It's pointless. */ + static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, diff --git a/util/grub-probe.c b/util/grub-probe.c index 54b9d03c6..795a9344e 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -173,10 +173,10 @@ probe (const char *path, char *device_name) { #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__) if (! grub_util_check_char_device (device_name)) - grub_util_error ("%s is not a character device", device_name); + grub_util_error (_("%s is not a character device"), device_name); #else if (! grub_util_check_block_device (device_name)) - grub_util_error ("%s is not a block device", device_name); + grub_util_error (_("%s is not a block device"), device_name); #endif } else @@ -186,7 +186,7 @@ probe (const char *path, char *device_name) } if (! device_name) - grub_util_error ("cannot find a device for %s (is /dev mounted?)", path); + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path); if (print == PRINT_DEVICE) { @@ -196,7 +196,8 @@ probe (const char *path, char *device_name) drive_name = grub_util_get_grub_dev (device_name); if (! drive_name) - grub_util_error ("cannot find a GRUB drive for %s. Check your device.map", device_name); + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + device_name); if (print == PRINT_DRIVE) { @@ -207,7 +208,7 @@ probe (const char *path, char *device_name) grub_util_info ("opening %s", drive_name); dev = grub_device_open (drive_name); if (! dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); if (print == PRINT_ABSTRACTION) { @@ -233,7 +234,7 @@ probe (const char *path, char *device_name) fs = grub_fs_probe (dev); if (! fs) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); if (print == PRINT_FS) { @@ -243,7 +244,7 @@ probe (const char *path, char *device_name) { char *uuid; if (! fs->uuid) - grub_util_error ("%s does not support UUIDs", fs->name); + grub_util_error (_("%s does not support UUIDs"), fs->name); if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -254,10 +255,10 @@ probe (const char *path, char *device_name) { char *label; if (! fs->label) - grub_util_error ("%s does not support labels", fs->name); + grub_util_error (_("%s does not support labels"), fs->name); if (fs->label (dev, &label) != GRUB_ERR_NONE) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); printf ("%s\n", label); } @@ -287,9 +288,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTION]... [PATH|DEVICE]\n\ \n\ Probe device information for a given path (or device, if the -d option is given).\n\ @@ -303,7 +304,7 @@ Probe device information for a given path (or device, if the -d option is given) -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); exit (status); @@ -385,13 +386,13 @@ main (int argc, char *argv[]) /* Obtain ARGUMENT. */ if (optind >= argc) { - fprintf (stderr, "No path or device is specified.\n"); + fprintf (stderr, _("No path or device is specified.\n")); usage (1); } if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } diff --git a/util/grub-setup.c b/util/grub-setup.c index d3f6fe8b8..f185ed747 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -125,8 +125,8 @@ write_rootdev (char *core_img, grub_device_t root_dev, if (root_dev->disk->partition->parent) { if (root_dev->disk->partition->parent->parent) - grub_util_error ("Installing on doubly nested partitions is " - "not supported"); + grub_util_error (_("Installing on doubly nested partitions " + "is not supported")); dos_part = root_dev->disk->partition->parent->number; bsd_part = root_dev->disk->partition->number; } @@ -283,22 +283,22 @@ setup (const char *dir, grub_util_info ("Opening root"); root_dev = grub_device_open (root); if (! root_dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); grub_util_info ("Opening dest"); dest_dev = grub_device_open (dest); if (! dest_dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); #ifdef GRUB_MACHINE_PCBIOS /* Read the original sector from the disk. */ tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); #endif #ifdef GRUB_MACHINE_PCBIOS @@ -421,14 +421,14 @@ setup (const char *dir, if (dest_partmap && !dest_partmap->embed) { - grub_util_warn ("Partition style '%s' doesn't support embeding", + grub_util_warn (_("Partition style '%s' doesn't support embeding"), dest_partmap->name); goto unable_to_embed; } if (fs && !fs->embed) { - grub_util_warn ("File system '%s' doesn't support embeding", + grub_util_warn (_("File system '%s' doesn't support embeding"), fs->name); goto unable_to_embed; } @@ -443,13 +443,13 @@ setup (const char *dir, if (!err && nsec < core_sectors) { err = grub_error (GRUB_ERR_OUT_OF_RANGE, - "Your embedding area is unusually small. " - "core.img won't fit in it."); + N_("Your embedding area is unusually small. " + "core.img won't fit in it.")); } if (err) { - grub_util_warn ("%s", grub_errmsg); + grub_util_warn ("%s", _(grub_errmsg)); grub_errno = GRUB_ERR_NONE; goto unable_to_embed; } @@ -466,7 +466,7 @@ setup (const char *dir, block--; if ((char *) block <= core_img) - grub_util_error ("No terminator in the core image"); + grub_util_error (_("No terminator in the core image")); } save_first_sector (sectors[0] + grub_partition_get_start (container), @@ -626,7 +626,7 @@ unable_to_embed: grub_file_filter_disable_compression (); file = grub_file_open (core_path_dev); if (! file) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); file->read_hook = save_first_sector; if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) @@ -687,8 +687,7 @@ unable_to_embed: /* Write the boot image onto the disk. */ if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, 0, GRUB_DISK_SECTOR_SIZE, boot_img)) - grub_util_error ("%s", grub_errmsg); - + grub_util_error ("%s", _(grub_errmsg)); grub_util_biosdisk_flush (root_dev->disk); grub_util_biosdisk_flush (dest_dev->disk); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index f72bea8a5..20a571191 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -23,6 +23,7 @@ #include #include #include +#include #endif #include @@ -53,6 +54,7 @@ grub_util_error (const char *fmt, ...) exit (1); } +#define _(x) x #endif static void @@ -106,7 +108,7 @@ find_obppath(char *of_path, const char *sysfs_path_orig) { kill_trailing_dir(sysfs_path); if (!strcmp(sysfs_path, "/sys")) - grub_util_error("'obppath' not found in parent dirs of %s", + grub_util_error(_("'obppath' not found in parent dirs of %s"), sysfs_path_orig); continue; } @@ -131,12 +133,12 @@ block_device_get_sysfs_path_and_link(const char *devicenode, snprintf(sysfs_path, sysfs_path_len, "/sys/block/%s", devicenode); if (!realpath (sysfs_path, rpath)) - grub_util_error ("cannot get the real path of `%s'", sysfs_path); + grub_util_error (_("cannot get the real path of `%s'"), sysfs_path); strcat(rpath, "/device"); if (!realpath (rpath, sysfs_path)) - grub_util_error ("cannot get the real path of `%s'", rpath); + grub_util_error (_("cannot get the real path of `%s'"), rpath); free (rpath); } @@ -247,12 +249,12 @@ vendor_is_ATA(const char *path) snprintf(buf, PATH_MAX, "%s/vendor", path); fd = open(buf, O_RDONLY); if (fd < 0) - grub_util_error ("cannot open 'vendor' node of `%s'", path); + grub_util_error (_("cannot open 'vendor' node of `%s'"), path); memset(buf, 0, PATH_MAX); err = read(fd, buf, PATH_MAX); if (err < 0) - grub_util_error ("cannot read 'vendor' node of `%s'", path); + grub_util_error (_("cannot read 'vendor' node of `%s'"), path); close(fd); @@ -288,7 +290,7 @@ check_sas (char *sysfs_path, int *tgt) fd = open(path, O_RDONLY); if (fd < 0) - grub_util_error("cannot open SAS PHY ID `%s'\n", path); + grub_util_error(_("cannot open SAS PHY ID `%s'\n"), path); memset (phy, 0, sizeof (phy)); read (fd, phy, sizeof (phy)); @@ -376,7 +378,7 @@ grub_util_devname_to_ofpath (const char *devname) name_buf = xmalloc (PATH_MAX); name_buf = realpath (devname, name_buf); if (! name_buf) - grub_util_error ("cannot get the real path of `%s'", devname); + grub_util_error (_("cannot get the real path of `%s'"), devname); device = get_basename (name_buf); devnode = strip_trailing_digits (name_buf); @@ -398,7 +400,7 @@ grub_util_devname_to_ofpath (const char *devname) New models have no floppy at all. */ strcpy (ofpath, "floppy"); else - grub_util_error ("unknown device type %s\n", device); + grub_util_error (_("unknown device type %s\n"), device); free (devnode); free (devicenode); @@ -414,7 +416,7 @@ int main(int argc, char **argv) if (argc != 2) { - printf("Usage: grub-ofpathname DEVICE\n"); + printf(_("Usage: %s DEVICE\n"), argv[0]); return 1; } diff --git a/util/misc.c b/util/misc.c index 72bedde0c..6ebaf30bc 100644 --- a/util/misc.c +++ b/util/misc.c @@ -89,10 +89,10 @@ grub_util_get_fp_size (FILE *fp) struct stat st; if (fflush (fp) == EOF) - grub_util_error ("fflush failed"); + grub_util_error (_("fflush failed")); if (fstat (fileno (fp), &st) == -1) - grub_util_error ("fstat failed"); + grub_util_error (_("fstat failed")); return st.st_size; } @@ -105,7 +105,7 @@ grub_util_get_image_size (const char *path) grub_util_info ("getting the size of %s", path); if (stat (path, &st) == -1) - grub_util_error ("cannot stat %s", path); + grub_util_error (_("cannot stat %s"), path); return st.st_size; } @@ -114,10 +114,10 @@ void grub_util_read_at (void *img, size_t size, off_t offset, FILE *fp) { if (fseeko (fp, offset, SEEK_SET) == -1) - grub_util_error ("seek failed"); + grub_util_error (_("seek failed")); if (fread (img, 1, size, fp) != size) - grub_util_error ("read failed"); + grub_util_error (_("read failed")); } char * @@ -134,7 +134,7 @@ grub_util_read_image (const char *path) fp = fopen (path, "rb"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); grub_util_read_at (img, size, 0, fp); @@ -155,10 +155,10 @@ grub_util_load_image (const char *path, char *buf) fp = fopen (path, "rb"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); if (fread (buf, 1, size, fp) != size) - grub_util_error ("cannot read %s", path); + grub_util_error (_("cannot read %s"), path); fclose (fp); } @@ -168,9 +168,9 @@ grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out) { grub_util_info ("writing 0x%x bytes at offset 0x%x", size, offset); if (fseeko (out, offset, SEEK_SET) == -1) - grub_util_error ("seek failed"); + grub_util_error (_("seek failed")); if (fwrite (img, 1, size, out) != size) - grub_util_error ("write failed"); + grub_util_error (_("write failed")); } void @@ -178,7 +178,7 @@ grub_util_write_image (const char *img, size_t size, FILE *out) { grub_util_info ("writing 0x%x bytes", size); if (fwrite (img, 1, size, out) != size) - grub_util_error ("write failed"); + grub_util_error (_("write failed")); } char * diff --git a/util/raid.c b/util/raid.c index 1e312491b..8de5fbac0 100644 --- a/util/raid.c +++ b/util/raid.c @@ -33,6 +33,7 @@ #include #include #include +#include char ** grub_util_raid_getmembers (const char *name, int bootable) @@ -46,26 +47,26 @@ grub_util_raid_getmembers (const char *name, int bootable) fd = open (name, O_RDONLY); if (fd == -1) - grub_util_error ("can't open %s: %s", name, strerror (errno)); + grub_util_error (_("can't open %s: %s"), name, strerror (errno)); ret = ioctl (fd, RAID_VERSION, &version); if (ret != 0) - grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno)); + grub_util_error (_("ioctl RAID_VERSION error: %s"), strerror (errno)); if ((version.major != 0 || version.minor != 90) && (version.major != 1 || version.minor != 0) && (version.major != 1 || version.minor != 1) && (version.major != 1 || version.minor != 2)) - grub_util_error ("unsupported RAID version: %d.%d", + grub_util_error (_("unsupported RAID version: %d.%d"), version.major, version.minor); if (bootable && (version.major != 0 || version.minor != 90)) - grub_util_error ("unsupported RAID version: %d.%d", + grub_util_error (_("unsupported RAID version: %d.%d"), version.major, version.minor); ret = ioctl (fd, GET_ARRAY_INFO, &info); if (ret != 0) - grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno)); + grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); @@ -74,7 +75,7 @@ grub_util_raid_getmembers (const char *name, int bootable) disk.number = i; ret = ioctl (fd, GET_DISK_INFO, &disk); if (ret != 0) - grub_util_error ("ioctl GET_DISK_INFO error: %s", strerror (errno)); + grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); if (disk.state & (1 << MD_DISK_ACTIVE)) { From f1f233ba430c27cbc6a327751bd3da53798cdf2f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:56:20 +0100 Subject: [PATCH 211/315] Add crypto support to grub-mount --- Makefile.util.def | 1 + util/grub-mount.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Makefile.util.def b/Makefile.util.def index 567747fc7..5f655b73d 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -246,6 +246,7 @@ program = { common = grub-core/disk/host.c; ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse'; diff --git a/util/grub-mount.c b/util/grub-mount.c index 434772eec..7c75acd15 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ static char *debug_str = NULL; static char **fuse_args = NULL; static int fuse_argc = 0; static int num_disks = 0; +static int mount_crypt = 0; static grub_err_t execute_command (char *name, int n, char **args) @@ -333,6 +335,13 @@ fuse_init (void) grub_free (host_file); } + if (mount_crypt) + { + char *argv[2] = { "-a", NULL}; + if (execute_command ("cryptomount", 1, argv)) + grub_util_error (_("cryptomount command fails: %s"), grub_errmsg); + } + grub_lvm_fini (); grub_mdraid09_fini (); grub_mdraid1x_fini (); @@ -378,6 +387,8 @@ fuse_init (void) static struct argp_option options[] = { {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, + {"zfs-key", 'K', N_("FILE|prompt"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -401,6 +412,42 @@ argp_parser (int key, char *arg, struct argp_state *state) root = arg; return 0; + case 'K': + if (strcmp (arg, "prompt") == 0) + { + char buf[1024]; + grub_printf ("Enter ZFS password: "); + if (grub_password_get (buf, 1023)) + { + grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); + } + } + else + { + FILE *f; + ssize_t real_size; + grub_uint8_t buf[1024]; + f = fopen (arg, "rb"); + if (!f) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + return 0; + } + real_size = fread (buf, 1, 1024, f); + if (real_size < 0) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + fclose (f); + return 0; + } + grub_zfs_add_key (buf, real_size, 0); + } + return 0; + + case 'C': + mount_crypt = 1; + return 0; + case 'd': debug_str = arg; return 0; From d8e62bbeb95c357ac597db5ce28df20f7a9d9823 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 01:19:06 +0100 Subject: [PATCH 212/315] gettextize --- util/grub-mount.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index 7c75acd15..f084fbf98 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -416,7 +416,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (strcmp (arg, "prompt") == 0) { char buf[1024]; - grub_printf ("Enter ZFS password: "); + grub_printf ("%s", _("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); @@ -430,13 +430,13 @@ argp_parser (int key, char *arg, struct argp_state *state) f = fopen (arg, "rb"); if (!f) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); return 0; } real_size = fread (buf, 1, 1024, f); if (real_size < 0) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); fclose (f); return 0; } @@ -507,7 +507,7 @@ main (int argc, char *argv[]) argp_parse (&argp, argc, argv, 0, 0, 0); if (num_disks < 2) - grub_util_error ("need an image and mountpoint"); + grub_util_error (_("need an image and mountpoint")); fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); fuse_args[fuse_argc] = images[num_disks - 1]; fuse_argc++; From ae60d685fad88cb461b6479ee28115c1d5251293 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 01:20:23 +0100 Subject: [PATCH 213/315] fill attr on readdir --- util/grub-mount.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index f084fbf98..a4be21738 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -281,7 +281,26 @@ fuse_readdir (const char *path, void *buf, const struct grub_dirhook_info *info); int call_fill (const char *filename, const struct grub_dirhook_info *info) { - fill (buf, filename, NULL, 0); + struct stat st; + grub_memset (&st, 0, sizeof (st)); + st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); + if (!info->dir) + { + grub_file_t file; + char *tmp; + tmp = xasprintf ("%s/%s", path, filename); + file = grub_file_open (tmp); + free (tmp); + if (! file) + return translate_error (); + st.st_size = file->size; + grub_file_close (file); + } + st.st_blksize = 512; + st.st_blocks = (st.st_size + 511) >> 9; + st.st_atime = st.st_mtime = st.st_ctime + = info->mtimeset ? info->mtime : 0; + fill (buf, filename, &st, 0); return 0; } From 2b23074a0c082219fe4490fa05b13a481b34b41e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 16:29:04 +0100 Subject: [PATCH 214/315] Move assembly code to C by using intwrap. It increases core size by 88 bytes but improves compatibility and maintainability. * grub-core/kern/i386/pc/startup.S (grub_console_putchar): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_putchar_real): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_getkey): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_getxy): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_getxy): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_gotoxy): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_gotoxy): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_cls): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_cls): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Moved to .. * grub-core/term/i386/pc/console.c (grub_console_setcursor): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_get_rtc): Moved to .. * grub-core/kern/i386/pc/init.c (grub_get_rtc): ... here. Translated to C. * grub-core/term/i386/pc/console.c (int10_9): New function. (grub_console_putchar): Likewise. * include/grub/i386/pc/console.h: Removed the not anymore shared functions. --- ChangeLog | 31 +++ grub-core/kern/i386/pc/init.c | 16 ++ grub-core/kern/i386/pc/startup.S | 365 ------------------------------- grub-core/term/i386/pc/console.c | 219 +++++++++++++++++++ include/grub/i386/pc/console.h | 10 - 5 files changed, 266 insertions(+), 375 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7743aa2d4..3d8bd25e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2011-11-12 Vladimir Serbinenko + + Move assembly code to C by using intwrap. It increases core size + by 88 bytes but improves compatibility and maintainability. + + * grub-core/kern/i386/pc/startup.S (grub_console_putchar): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_putchar_real): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_getkey): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_getxy): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_getxy): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_gotoxy): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_gotoxy): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_cls): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_cls): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Moved to .. + * grub-core/term/i386/pc/console.c (grub_console_setcursor): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_get_rtc): Moved to .. + * grub-core/kern/i386/pc/init.c (grub_get_rtc): ... here. + Translated to C. + * grub-core/term/i386/pc/console.c (int10_9): New function. + (grub_console_putchar): Likewise. + * include/grub/i386/pc/console.h: Removed the not anymore shared + functions. + 2011-11-12 Vladimir Serbinenko Move grub_chainloader_real_boot out of the kernel. diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index be26fdea1..6fbfab3b8 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -47,6 +47,22 @@ static int num_regions; void (*grub_pc_net_config) (char **device, char **path); +/* + * return the real time in ticks, of which there are about + * 18-20 per second + */ +grub_uint32_t +grub_get_rtc (void) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x1a, ®s); + + return (regs.ecx << 16) | (regs.edx & 0xffff); +} + void grub_machine_get_bootlocation (char **device, char **path) { diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index df8992278..94d4f02ee 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -464,371 +464,6 @@ FUNCTION(grub_exit) ljmp $0xf000, $0xfff0 .code32 -/* - * void grub_console_putchar (int c) - * - * Put the character C on the console. Because GRUB wants to write a - * character with an attribute, this implementation is a bit tricky. - * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh - * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, - * save the current position, restore the original position, write the - * character and the attribute, and restore the current position. - * - * The reason why this is so complicated is that there is no easy way to - * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't - * support setting a background attribute. - */ -FUNCTION(grub_console_putchar) - /* Retrieve the base character. */ - movl 0(%edx), %edx - pusha - movb EXT_C(grub_console_cur_color), %bl - - call prot_to_real - .code16 - movb %dl, %al - xorb %bh, %bh - - /* use teletype output if control character */ - cmpb $0x7, %al - je 1f - cmpb $0x8, %al - je 1f - cmpb $0xa, %al - je 1f - cmpb $0xd, %al - je 1f - - /* save the character and the attribute on the stack */ - pushw %ax - pushw %bx - - /* get the current position */ - movb $0x3, %ah - int $0x10 - - /* check the column with the width */ - cmpb $79, %dl - jl 2f - - /* print CR and LF, if next write will exceed the width */ - movw $0x0e0d, %ax - int $0x10 - movb $0x0a, %al - int $0x10 - - /* get the current position */ - movb $0x3, %ah - int $0x10 - -2: - /* restore the character and the attribute */ - popw %bx - popw %ax - - /* write the character with the attribute */ - movb $0x9, %ah - movw $1, %cx - int $0x10 - - /* move the cursor forward */ - incb %dl - movb $0x2, %ah - int $0x10 - - jmp 3f - -1: movw $1, %bx - movb $0xe, %ah - int $0x10 - -3: DATA32 call real_to_prot - .code32 - - popa - ret - - -LOCAL(bypass_table): - .word 0x011b, 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' - .word 0x1c00 | '\n' -LOCAL(bypass_table_end): - -/* - * int grub_console_getkey (void) - * if there is a character pending, return it; otherwise return -1 - * BIOS call "INT 16H Function 01H" to check whether a character is pending - * Call with %ah = 0x1 - * Return: - * If key waiting to be input: - * %ah = keyboard scan code - * %al = ASCII character - * Zero flag = clear - * else - * Zero flag = set - * BIOS call "INT 16H Function 00H" to read character from keyboard - * Call with %ah = 0x0 - * Return: %ah = keyboard scan code - * %al = ASCII character - */ - -FUNCTION(grub_console_getkey) - pushl %ebp - pushl %edi - - call prot_to_real - .code16 - - /* - * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would - * cause the machine to hang at the second keystroke. However, we can - * work around this problem by ensuring the presence of keystroke with - * INT 16/AH = 1 before calling INT 16/AH = 0. - */ - - movb $1, %ah - int $0x16 - jz notpending - - movb $0, %ah - int $0x16 - - xorl %edx, %edx - movw %ax, %dx /* real_to_prot uses %eax */ - - DATA32 call real_to_prot - .code32 - - movl $0xff, %eax - testl %eax, %edx - jz 1f - - andl %edx, %eax - cmpl $0x20, %eax - jae 2f - movl %edx, %eax - leal LOCAL(bypass_table), %edi - movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx - repne scasw - jz 3f - - andl $0xff, %eax - addl $(('a' - 1) | GRUB_TERM_CTRL), %eax - jmp 2f -3: - andl $0xff, %eax - jmp 2f - -1: movl %edx, %eax - shrl $8, %eax - orl $GRUB_TERM_EXTENDED, %eax -2: - popl %edi - popl %ebp - ret - -notpending: - .code16 - DATA32 call real_to_prot - .code32 -#if GRUB_TERM_NO_KEY != 0 -#error Fix this asm code -#endif - jmp 2b - - -/* - * grub_uint16_t grub_console_getxy (void) - * BIOS call "INT 10H Function 03h" to get cursor position - * Call with %ah = 0x03 - * %bh = page - * Returns %ch = starting scan line - * %cl = ending scan line - * %dh = row (0 is top) - * %dl = column (0 is left) - */ - - -FUNCTION(grub_console_getxy) - pushl %ebp - pushl %ebx /* save EBX */ - - call prot_to_real - .code16 - - xorb %bh, %bh /* set page to 0 */ - movb $0x3, %ah - int $0x10 /* get cursor position */ - - DATA32 call real_to_prot - .code32 - - movb %dl, %ah - movb %dh, %al - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y) - * BIOS call "INT 10H Function 02h" to set cursor position - * Call with %ah = 0x02 - * %bh = page - * %dh = row (0 is top) - * %dl = column (0 is left) - */ - - -FUNCTION(grub_console_gotoxy) - pushl %ebp - pushl %ebx /* save EBX */ - - movb %cl, %dh /* %dh = y */ - /* %dl = x */ - - call prot_to_real - .code16 - - xorb %bh, %bh /* set page to 0 */ - movb $0x2, %ah - int $0x10 /* set cursor position */ - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_cls (void) - * BIOS call "INT 10H Function 09h" to write character and attribute - * Call with %ah = 0x09 - * %al = (character) - * %bh = (page number) - * %bl = (attribute) - * %cx = (number of times) - */ - -FUNCTION(grub_console_cls) - pushl %ebp - pushl %ebx /* save EBX */ - - call prot_to_real - .code16 - - /* move the cursor to the beginning */ - movb $0x02, %ah - xorb %bh, %bh - xorw %dx, %dx - int $0x10 - - /* write spaces to the entire screen */ - movw $0x0920, %ax - movw $0x07, %bx - movw $(80 * 25), %cx - int $0x10 - - /* move back the cursor */ - movb $0x02, %ah - int $0x10 - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_setcursor (int on) - * BIOS call "INT 10H Function 01h" to set cursor type - * Call with %ah = 0x01 - * %ch = cursor starting scanline - * %cl = cursor ending scanline - */ - -console_cursor_state: - .byte 1 -console_cursor_shape: - .word 0 - -FUNCTION(grub_console_setcursor) - pushl %ebp - pushl %ebx - - /* push ON */ - pushl %edx - - /* check if the standard cursor shape has already been saved */ - movw console_cursor_shape, %ax - testw %ax, %ax - jne 1f - - call prot_to_real - .code16 - - movb $0x03, %ah - xorb %bh, %bh - int $0x10 - - DATA32 call real_to_prot - .code32 - - cmp %cl, %ch - jb 3f - movw $0x0d0e, %cx -3: - movw %cx, console_cursor_shape -1: - /* set %cx to the designated cursor shape */ - movw $0x2000, %cx - popl %eax - testl %eax, %eax - jz 2f - movw console_cursor_shape, %cx -2: - call prot_to_real - .code16 - - movb $0x1, %ah - int $0x10 - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - -/* - * grub_get_rtc() - * return the real time in ticks, of which there are about - * 18-20 per second - */ -FUNCTION(grub_get_rtc) - pushl %ebp - - call prot_to_real /* enter real mode */ - .code16 - - /* %ax is already zero */ - int $0x1a - - DATA32 call real_to_prot - .code32 - - movl %ecx, %eax - shll $16, %eax - movw %dx, %ax - - popl %ebp - ret - /* * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry); */ diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c index 0efeafe4e..7cf5ffc5f 100644 --- a/grub-core/term/i386/pc/console.c +++ b/grub-core/term/i386/pc/console.c @@ -20,6 +20,225 @@ #include #include #include +#include + +static void +int10_9 (grub_uint8_t ch, grub_uint16_t n) +{ + struct grub_bios_int_registers regs; + + regs.eax = ch | 0x0900; + regs.ebx = grub_console_cur_color & 0xff; + regs.ecx = n; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * BIOS call "INT 10H Function 03h" to get cursor position + * Call with %ah = 0x03 + * %bh = page + * Returns %ch = starting scan line + * %cl = ending scan line + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +static grub_uint16_t +grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x0300; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + + return ((regs.edx & 0xff) << 8) | ((regs.edx & 0xff00) >> 8); +} + +/* + * BIOS call "INT 10H Function 02h" to set cursor position + * Call with %ah = 0x02 + * %bh = page + * %dh = row (0 is top) + * %dl = column (0 is left) + */ +static void +grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) +{ + struct grub_bios_int_registers regs; + + /* set page to 0 */ + regs.ebx = 0; + regs.eax = 0x0200; + regs.edx = (y << 8) | x; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * + * Put the character C on the console. Because GRUB wants to write a + * character with an attribute, this implementation is a bit tricky. + * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh + * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, + * save the current position, restore the original position, write the + * character and the attribute, and restore the current position. + * + * The reason why this is so complicated is that there is no easy way to + * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't + * support setting a background attribute. + */ +static void +grub_console_putchar_real (grub_uint8_t c) +{ + struct grub_bios_int_registers regs; + grub_uint16_t pos; + + if (c == 7 || c == 8 || c == 0xa || c == 0xd) + { + regs.eax = c | 0x0e00; + regs.ebx = 0x0001; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + return; + } + + /* get the current position */ + pos = grub_console_getxy (NULL); + + /* check the column with the width */ + if ((pos & 0xff00) >= (79 << 8)) + { + grub_console_putchar_real (0x0d); + grub_console_putchar_real (0x0a); + /* get the current position */ + pos = grub_console_getxy (NULL); + } + + /* write the character with the attribute */ + int10_9 (c, 1); + + grub_console_gotoxy (NULL, ((pos & 0xff00) >> 8) + 1, (pos & 0xff)); +} + +static void +grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) +{ + grub_console_putchar_real (c->base); +} + +/* + * BIOS call "INT 10H Function 09h" to write character and attribute + * Call with %ah = 0x09 + * %al = (character) + * %bh = (page number) + * %bl = (attribute) + * %cx = (number of times) + */ +static void +grub_console_cls (struct grub_term_output *term) +{ + /* move the cursor to the beginning */ + grub_console_gotoxy (term, 0, 0); + + /* write spaces to the entire screen */ + int10_9 (' ', 80 * 25); + + /* move back the cursor */ + grub_console_gotoxy (term, 0, 0); +} + +/* + * void grub_console_setcursor (int on) + * BIOS call "INT 10H Function 01h" to set cursor type + * Call with %ah = 0x01 + * %ch = cursor starting scanline + * %cl = cursor ending scanline + */ +static void +grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) +{ + static grub_uint16_t console_cursor_shape = 0; + struct grub_bios_int_registers regs; + + /* check if the standard cursor shape has already been saved */ + if (!console_cursor_shape) + { + regs.eax = 0x0300; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + console_cursor_shape = regs.ecx; + if ((console_cursor_shape >> 8) >= (console_cursor_shape & 0xff)) + console_cursor_shape = 0x0d0e; + } + /* set %cx to the designated cursor shape */ + regs.ecx = on ? console_cursor_shape : 0x2000; + regs.eax = 0x0100; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * if there is a character pending, return it; otherwise return -1 + * BIOS call "INT 16H Function 01H" to check whether a character is pending + * Call with %ah = 0x1 + * Return: + * If key waiting to be input: + * %ah = keyboard scan code + * %al = ASCII character + * Zero flag = clear + * else + * Zero flag = set + * BIOS call "INT 16H Function 00H" to read character from keyboard + * Call with %ah = 0x0 + * Return: %ah = keyboard scan code + * %al = ASCII character + */ + +static int +grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) +{ + const grub_uint16_t bypass_table[] = { + 0x0100 | '\e', 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r', 0x1c00 | '\n' + }; + struct grub_bios_int_registers regs; + unsigned i; + + /* + * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would + * cause the machine to hang at the second keystroke. However, we can + * work around this problem by ensuring the presence of keystroke with + * INT 16/AH = 1 before calling INT 16/AH = 0. + */ + + regs.eax = 0x0100; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x16, ®s); + if (regs.flags & GRUB_CPU_INT_FLAGS_ZERO) + return GRUB_TERM_NO_KEY; + + regs.eax = 0x0000; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x16, ®s); + if (!(regs.eax & 0xff)) + return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; + + if ((regs.eax & 0xff) >= ' ') + return regs.eax & 0xff; + + for (i = 0; i < ARRAY_SIZE (bypass_table); i++) + if (bypass_table[i] == (regs.eax & 0xffff)) + return regs.eax & 0xff; + + return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); +} static const struct grub_machine_bios_data_area *bios_data_area = (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 1631a40ad..f752b9a25 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -26,16 +26,6 @@ #include #include -/* These are global to share code between C and asm. */ -int grub_console_getkey (struct grub_term_input *term); -grub_uint16_t grub_console_getxy (struct grub_term_output *term); -void grub_console_gotoxy (struct grub_term_output *term, - grub_uint8_t x, grub_uint8_t y); -void grub_console_cls (struct grub_term_output *term); -void grub_console_setcursor (struct grub_term_output *term, int on); -void grub_console_putchar (struct grub_term_output *term, - const struct grub_unicode_glyph *c); - /* Initialize the console system. */ void grub_console_init (void); From e9d3421c050df3f3b77b5f9bceb758d663fb229d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 19:18:42 +0100 Subject: [PATCH 215/315] * configure.ac: Add -fno-asynchronous-unwind-tables. --- ChangeLog | 4 ++++ configure.ac | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3d8bd25e7..409a41ca5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * configure.ac: Add -fno-asynchronous-unwind-tables. + 2011-11-12 Vladimir Serbinenko Move assembly code to C by using intwrap. It increases core size diff --git a/configure.ac b/configure.ac index 3d6cc9a9e..7699e8330 100644 --- a/configure.ac +++ b/configure.ac @@ -413,6 +413,23 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" fi +# By default, GCC 4.6 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_asynchronous_unwind_tables=yes], + [grub_cv_cc_fno_asynchronous_unwind_tables=no]) + CFLAGS="$SAVE_CFLAGS" +]) + +if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" +fi + grub_apple_target_cc if test x$grub_cv_apple_target_cc = xyes ; then TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1" From 60240b8bc1a501951944c9e07d094c9e5e5e7084 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 19:53:25 +0100 Subject: [PATCH 216/315] Use decompressors framework on i386-pc. It increases core size by 46 bytes but improves compatibility and maintainability. * grub-core/Makefile.core.def (lzma_decompress): New image. (kernel): Add i386_pc_ldflags. * grub-core/kern/i386/pc/startup.S: Move intial part to .. * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers to real_to_prot, prot_to_real and device info. * include/grub/offsets.h: Renamed decompressor offsets. * util/grub-mkimage.c (grub_compression_t): New cmpression lzma. (image_target_desc): Remove raw_size and rename decompressor fields. (compress_kernel): Handle lzma. (generate_image): Handle decompressors on i386-pc. --- ChangeLog | 16 + grub-core/Makefile.core.def | 11 +- grub-core/boot/i386/pc/lnxboot.S | 8 +- .../{kern => boot}/i386/pc/lzma_decode.S | 0 grub-core/boot/i386/pc/startup_raw.S | 369 +++++++++++++++++ grub-core/boot/mips/startup_raw.S | 6 +- grub-core/kern/i386/int.S | 4 +- grub-core/kern/i386/pc/init.c | 3 +- grub-core/kern/i386/pc/startup.S | 392 ++---------------- grub-core/kern/i386/realmode.S | 27 ++ include/grub/offsets.h | 16 +- util/grub-mkimage.c | 235 ++++++----- 12 files changed, 601 insertions(+), 486 deletions(-) rename grub-core/{kern => boot}/i386/pc/lzma_decode.S (100%) create mode 100644 grub-core/boot/i386/pc/startup_raw.S diff --git a/ChangeLog b/ChangeLog index 409a41ca5..eeb9bda57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-11-12 Vladimir Serbinenko + + Use decompressors framework on i386-pc. It increases core size + by 46 bytes but improves compatibility and maintainability. + + * grub-core/Makefile.core.def (lzma_decompress): New image. + (kernel): Add i386_pc_ldflags. + * grub-core/kern/i386/pc/startup.S: Move intial part to .. + * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers + to real_to_prot, prot_to_real and device info. + * include/grub/offsets.h: Renamed decompressor offsets. + * util/grub-mkimage.c (grub_compression_t): New cmpression lzma. + (image_target_desc): Remove raw_size and rename decompressor fields. + (compress_kernel): Handle lzma. + (generate_image): Handle decompressors on i386-pc. + 2011-11-12 Vladimir Serbinenko * configure.ac: Add -fno-asynchronous-unwind-tables. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 9590188fb..18264f98f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -34,7 +34,7 @@ kernel = { ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment'; i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; @@ -356,6 +356,15 @@ image = { enable = mips; }; +image = { + name = lzma_decompress; + i386_pc = boot/i386/pc/startup_raw.S; + + objcopyflags = '-O binary'; + ldflags = '-Wl,-Ttext,0x8200'; + enable = i386_pc; +}; + image = { name = fwstart; mips_loongson = boot/mips/loongson/fwstart.S; diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index bb43ed73c..e5227d174 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -199,12 +199,8 @@ real_code_2: 1: - movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx -#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200 - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx -#else - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx -#endif + movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx + addl $((0x9000 - 0x8200) - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx 2: call LOCAL(move_memory) diff --git a/grub-core/kern/i386/pc/lzma_decode.S b/grub-core/boot/i386/pc/lzma_decode.S similarity index 100% rename from grub-core/kern/i386/pc/lzma_decode.S rename to grub-core/boot/i386/pc/lzma_decode.S diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S new file mode 100644 index 000000000..4820e3442 --- /dev/null +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -0,0 +1,369 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + .file "startup_raw.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: +LOCAL (base): + /* + * Guarantee that "main" is loaded at 0x0:0x8200. + */ +#ifdef __APPLE__ + ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000) +#else + ljmp $0, $ABS(LOCAL (codestart)) +#endif + + /* + * This is a special data area. + */ + + . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE +LOCAL(compressed_size): + .long 0 + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE +LOCAL(uncompressed_size): + .long 0 + + . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART +LOCAL(dos_part): + .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART +LOCAL(bsd_part): + .long 0xFFFFFFFF + + . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY +reed_solomon_redundancy: + .long 0 + +/* + * This is the area for all of the special variables. + */ + +LOCAL(boot_drive): + .byte 0 + +/* the real mode code continues... */ +LOCAL (codestart): + cli /* we're not safe here! */ + + /* set up %ds, %ss, and %es */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + + /* set up the real mode/BIOS stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp + movl %ebp, %esp + + sti /* we're safe again */ + + /* save the boot drive */ + ADDR32 movb %dl, LOCAL(boot_drive) + + /* reset disk system (%ah = 0) */ + int $0x13 + + /* transition to protected mode */ + DATA32 call real_to_prot + + /* The ".code32" directive takes GAS out of 16-bit mode. */ + .code32 + + incl %eax + call grub_gate_a20 + + movl LOCAL(compressed_size), %edx + addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx + movl reed_solomon_redundancy, %ecx + leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax + call EXT_C (grub_reed_solomon_recover) + jmp post_reed_solomon + +#include + + .text + + . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + * This uses the a.out kludge to load raw binary to the area starting at 1MB, + * and relocates itself after loaded. + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long (1 << 16) + /* checksum */ + .long -0x1BADB002 - (1 << 16) + /* header addr */ + .long multiboot_header - _start + 0x100000 + 0x200 + /* load addr */ + .long 0x100000 + /* load end addr */ + .long 0 + /* bss end addr */ + .long 0 + /* entry addr */ + .long multiboot_entry - _start + 0x100000 + 0x200 + +multiboot_entry: + .code32 + /* obtain the boot device */ + movl 12(%ebx), %edx + + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp + movl %ebp, %esp + + /* relocate the code */ + movl $(LOCAL(decompressor_end) + 0x200), %ecx + addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx + movl $0x100000, %esi + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi + cld + rep + movsb + /* jump to the real address */ + movl $multiboot_trampoline, %eax + jmp *%eax + +multiboot_trampoline: + /* fill the boot information */ + movl %edx, %eax + shrl $8, %eax + xorl %ebx, %ebx + cmpb $0xFF, %ah + je 1f + movb %ah, %bl + movl %ebx, LOCAL(dos_part) +1: + cmpb $0xFF, %al + je 2f + movb %al, %bl + movl %ebx, LOCAL(bsd_part) +2: + shrl $24, %edx + movb %dl, LOCAL(boot_drive) + movb $0xFF, %dh + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp + /* enter the usual booting */ + call prot_to_real + .code16 + jmp LOCAL (codestart) + + .code32 + +post_reed_solomon: + +#ifdef ENABLE_LZMA + movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi + movl $LOCAL(decompressor_end), %esi + pushl %edi + movl LOCAL (uncompressed_size), %ecx + leal (%edi, %ecx), %ebx + call _LzmaDecodeA + /* _LzmaDecodeA clears DF, so no need to run cld */ + popl %esi +#endif + + movb LOCAL(boot_drive), %dl + movl LOCAL(dos_part), %eax + movl LOCAL(bsd_part), %ebx + movl $prot_to_real, %edi + movl $real_to_prot, %ecx + jmp *%esi + +#include "../../../kern/i386/realmode.S" + +/* + * grub_gate_a20(int on) + * + * Gate address-line 20 for high memory. + * + * This routine is probably overconservative in what it does, but so what? + * + * It also eats any keystrokes in the keyboard buffer. :-( + */ + +grub_gate_a20: + movl %eax, %edx + +gate_a20_test_current_state: + /* first of all, test if already in a good state */ + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_bios + ret + +gate_a20_try_bios: + /* second, try a BIOS call */ + pushl %ebp + call prot_to_real + + .code16 + movw $0x2400, %ax + testb %dl, %dl + jz 1f + incw %ax +1: int $0x15 + + DATA32 call real_to_prot + .code32 + + popl %ebp + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_system_control_port_a + ret + +gate_a20_try_system_control_port_a: + /* + * 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 + testb %dl, %dl + jz 6f + orb $0x02, %al +6: 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. */ + testb %dl, %dl + jz 7f + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_keyboard_controller +7: ret + +gate_a20_flush_keyboard_buffer: + inb $0x64 + andb $0x02, %al + jnz gate_a20_flush_keyboard_buffer +2: + inb $0x64 + andb $0x01, %al + jz 3f + inb $0x60 + jmp 2b +3: + ret + +gate_a20_try_keyboard_controller: + /* third, try the keyboard controller */ + call gate_a20_flush_keyboard_buffer + + movb $0xd1, %al + outb $0x64 +4: + inb $0x64 + andb $0x02, %al + jnz 4b + + movb $0xdd, %al + testb %dl, %dl + jz 5f + orb $0x02, %al +5: outb $0x60 + call gate_a20_flush_keyboard_buffer + + /* output a dummy command (USB keyboard hack) */ + movb $0xff, %al + outb $0x64 + call gate_a20_flush_keyboard_buffer + + call gate_a20_check_state + cmpb %al, %dl + /* everything failed, so restart from the beginning */ + jnz gate_a20_try_bios + ret + +gate_a20_check_state: + /* iterate the checking for a while */ + movl $100, %ecx +1: + call 3f + cmpb %al, %dl + jz 2f + loop 1b +2: + ret +3: + pushl %ebx + pushl %ecx + xorl %eax, %eax + /* compare the byte at 0x8000 with that at 0x108000 */ + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx + pushl %ebx + /* save the original byte in CL */ + movb (%ebx), %cl + /* store the value at 0x108000 in AL */ + addl $0x100000, %ebx + movb (%ebx), %al + /* try to set one less value at 0x8000 */ + popl %ebx + movb %al, %ch + decb %ch + movb %ch, (%ebx) + /* serialize */ + outb %al, $0x80 + outb %al, $0x80 + /* obtain the value at 0x108000 in CH */ + pushl %ebx + addl $0x100000, %ebx + movb (%ebx), %ch + /* this result is 1 if A20 is on or 0 if it is off */ + subb %ch, %al + xorb $1, %al + /* restore the original */ + popl %ebx + movb %cl, (%ebx) + popl %ecx + popl %ebx + ret + +#ifdef ENABLE_LZMA +#include "lzma_decode.S" +#endif + + .p2align 2 + +LOCAL(decompressor_end): diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index aefd387b6..e76926677 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -38,13 +38,13 @@ start: bal codestart nop base: - . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE + . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE uncompressed_size: .long 0 - . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR uncompressed_addr: .long 0 codestart: diff --git a/grub-core/kern/i386/int.S b/grub-core/kern/i386/int.S index 58ccfdaab..7a2b7808a 100644 --- a/grub-core/kern/i386/int.S +++ b/grub-core/kern/i386/int.S @@ -47,7 +47,7 @@ FUNCTION(grub_bios_interrupt) movl 24(%edx), %esi movl 28(%edx), %edx - call prot_to_real + PROT_TO_REAL .code16 pushf cli @@ -98,7 +98,7 @@ intno: movw %ax, LOCAL(bios_register_es) popf - DATA32 call real_to_prot + REAL_TO_PROT .code32 popl %eax diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 6fbfab3b8..da7230c33 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -156,8 +156,7 @@ grub_machine_init (void) int grub_lower_mem; #endif - grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + ((_edata - _start) - GRUB_KERNEL_MACHINE_RAW_SIZE); + grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); /* Initialize the console as early as possible. */ grub_console_init (); diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 94d4f02ee..058f9efa7 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,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 @@ -43,203 +43,30 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include - -#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) .file "startup.S" .text - /* Tell GAS to generate 16-bit instructions so that this code works - in real mode. */ - .code16 - .globl start, _start start: _start: -LOCAL (base): - /* - * Guarantee that "main" is loaded at 0x0:0x8200. - */ -#ifdef __APPLE__ - ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000) -#else - ljmp $0, $ABS(LOCAL (codestart)) -#endif - - /* - * This is a special data area. - */ - - . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE -VARIABLE(grub_total_module_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE -VARIABLE(grub_compressed_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART -VARIABLE(grub_install_dos_part) - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART -VARIABLE(grub_install_bsd_part) - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY -reed_solomon_redundancy: - .long 0 - -#ifdef APPLE_CC -bss_start: - .long 0 -bss_end: - .long 0 -#endif -/* - * This is the area for all of the special variables. - */ - -VARIABLE(grub_boot_drive) - .byte 0 - -/* the real mode code continues... */ -LOCAL (codestart): - cli /* we're not safe here! */ - - /* set up %ds, %ss, and %es */ - xorw %ax, %ax - movw %ax, %ds - movw %ax, %ss - movw %ax, %es - - /* set up the real mode/BIOS stack */ - movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp - movl %ebp, %esp - - sti /* we're safe again */ - - /* save the boot drive */ - ADDR32 movb %dl, EXT_C(grub_boot_drive) - - /* reset disk system (%ah = 0) */ - int $0x13 - - /* transition to protected mode */ - DATA32 call real_to_prot - - /* The ".code32" directive takes GAS out of 16-bit mode. */ .code32 - incl %eax - call grub_gate_a20 - - movl EXT_C(grub_compressed_size), %edx - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx - movl reed_solomon_redundancy, %ecx - leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax - call EXT_C (grub_reed_solomon_recover) - jmp post_reed_solomon - -#include - - .text - - . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART -/* - * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). - * This uses the a.out kludge to load raw binary to the area starting at 1MB, - * and relocates itself after loaded. - */ - .p2align 2 /* force 4-byte alignment */ -multiboot_header: - /* magic */ - .long 0x1BADB002 - /* flags */ - .long (1 << 16) - /* checksum */ - .long -0x1BADB002 - (1 << 16) - /* header addr */ - .long multiboot_header - _start + 0x100000 + 0x200 - /* load addr */ - .long 0x100000 - /* load end addr */ - .long 0 - /* bss end addr */ - .long 0 - /* entry addr */ - .long multiboot_entry - _start + 0x100000 + 0x200 - -multiboot_entry: - .code32 - /* obtain the boot device */ - movl 12(%ebx), %edx - - movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp - movl %ebp, %esp - - /* relocate the code */ - movl $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx - addl EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx - movl $0x100000, %esi - movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi - cld - rep - movsb - /* jump to the real address */ - movl $multiboot_trampoline, %eax - jmp *%eax - -multiboot_trampoline: - /* fill the boot information */ - movl %edx, %eax - shrl $8, %eax - xorl %ebx, %ebx - cmpb $0xFF, %ah - je 1f - movb %ah, %bl - movl %ebx, EXT_C(grub_install_dos_part) -1: - cmpb $0xFF, %al - je 2f - movb %al, %bl - movl %ebx, EXT_C(grub_install_bsd_part) -2: - shrl $24, %edx - movb $0xFF, %dh - /* enter the usual booting */ - call prot_to_real - jmp LOCAL (codestart) - -post_reed_solomon: - -#ifdef ENABLE_LZMA - movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi - movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi - pushl %edi - pushl %esi - movl $(BSS_START_SYMBOL - _start), %ecx - addl EXT_C(grub_total_module_size), %ecx - subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx - pushl %ecx - leal (%edi, %ecx), %ebx - call _LzmaDecodeA - /* _LzmaDecodeA clears DF, so no need to run cld */ - popl %ecx - popl %edi - popl %esi -#endif + movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi) + movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi) /* copy back the decompressed part (except the modules) */ - subl EXT_C(grub_total_module_size), %ecx + movl $(_edata - _start), %ecx + movl $(_start), %edi rep movsb + movl $LOCAL (cont), %esi + jmp *%esi +LOCAL(cont): + #if 0 /* copy modules before cleaning out the bss */ movl EXT_C(grub_total_module_size), %ecx @@ -255,24 +82,14 @@ post_reed_solomon: movsb #endif -#ifdef APPLE_CC - /* clean out the bss */ - bss_start_abs = ABS (bss_start) - bss_end_abs = ABS (bss_end) + movl %eax, %esi - movl bss_start_abs, %edi - - /* compute the bss length */ - movl bss_end_abs, %ecx - subl %edi, %ecx -#else /* clean out the bss */ movl $BSS_START_SYMBOL, %edi /* compute the bss length */ movl $END_SYMBOL, %ecx subl %edi, %ecx -#endif /* clean out */ xorl %eax, %eax @@ -280,172 +97,29 @@ post_reed_solomon: rep stosb + movl %esi, EXT_C(grub_install_dos_part) + movb %dl, EXT_C(grub_boot_drive) + movl %ebx, EXT_C(grub_install_bsd_part) + /* * Call the start of main body of C code. */ call EXT_C(grub_main) -#include "../realmode.S" +LOCAL(real_to_prot_addr): + .long 0 +LOCAL(prot_to_real_addr): + .long 0 -/* - * grub_gate_a20(int on) - * - * Gate address-line 20 for high memory. - * - * This routine is probably overconservative in what it does, but so what? - * - * It also eats any keystrokes in the keyboard buffer. :-( - */ + .macro PROT_TO_REAL + movl LOCAL(prot_to_real_addr), %eax + call *%eax + .endm -grub_gate_a20: - movl %eax, %edx - -gate_a20_test_current_state: - /* first of all, test if already in a good state */ - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_bios - ret - -gate_a20_try_bios: - /* second, try a BIOS call */ - pushl %ebp - call prot_to_real - - .code16 - movw $0x2400, %ax - testb %dl, %dl - jz 1f - incw %ax -1: int $0x15 - - DATA32 call real_to_prot - .code32 - - popl %ebp - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_system_control_port_a - ret - -gate_a20_try_system_control_port_a: - /* - * 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 - testb %dl, %dl - jz 6f - orb $0x02, %al -6: 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. */ - testb %dl, %dl - jz 7f - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_keyboard_controller -7: ret - -gate_a20_flush_keyboard_buffer: - inb $0x64 - andb $0x02, %al - jnz gate_a20_flush_keyboard_buffer -2: - inb $0x64 - andb $0x01, %al - jz 3f - inb $0x60 - jmp 2b -3: - ret - -gate_a20_try_keyboard_controller: - /* third, try the keyboard controller */ - call gate_a20_flush_keyboard_buffer - - movb $0xd1, %al - outb $0x64 -4: - inb $0x64 - andb $0x02, %al - jnz 4b - - movb $0xdd, %al - testb %dl, %dl - jz 5f - orb $0x02, %al -5: outb $0x60 - call gate_a20_flush_keyboard_buffer - - /* output a dummy command (USB keyboard hack) */ - movb $0xff, %al - outb $0x64 - call gate_a20_flush_keyboard_buffer - - call gate_a20_check_state - cmpb %al, %dl - /* everything failed, so restart from the beginning */ - jnz gate_a20_try_bios - ret - -gate_a20_check_state: - /* iterate the checking for a while */ - movl $100, %ecx -1: - call 3f - cmpb %al, %dl - jz 2f - loop 1b -2: - ret -3: - pushl %ebx - pushl %ecx - xorl %eax, %eax - /* compare the byte at 0x8000 with that at 0x108000 */ - movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx - pushl %ebx - /* save the original byte in CL */ - movb (%ebx), %cl - /* store the value at 0x108000 in AL */ - addl $0x100000, %ebx - movb (%ebx), %al - /* try to set one less value at 0x8000 */ - popl %ebx - movb %al, %ch - decb %ch - movb %ch, (%ebx) - /* serialize */ - outb %al, $0x80 - outb %al, $0x80 - /* obtain the value at 0x108000 in CH */ - pushl %ebx - addl $0x100000, %ebx - movb (%ebx), %ch - /* this result is 1 if A20 is on or 0 if it is off */ - subb %ch, %al - xorb $1, %al - /* restore the original */ - popl %ebx - movb %cl, (%ebx) - popl %ecx - popl %ebx - ret - -#ifdef ENABLE_LZMA -#include "lzma_decode.S" -#endif - -/* - * The code beyond this point is compressed. Assert that the uncompressed - * code fits GRUB_KERNEL_MACHINE_RAW_SIZE. - */ - . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE + .macro REAL_TO_PROT + movl LOCAL(real_to_prot_addr), %eax + DATA32 call *%ax + .endm /* * grub_exit() @@ -453,7 +127,7 @@ gate_a20_check_state: * Exit the system. */ FUNCTION(grub_exit) - call prot_to_real + PROT_TO_REAL .code16 /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 @@ -482,7 +156,7 @@ FUNCTION(grub_pxe_call) shll $16, %edx addl %eax, %edx - call prot_to_real + PROT_TO_REAL .code16 pushl %ebx @@ -494,7 +168,7 @@ FUNCTION(grub_pxe_call) addw $10, %sp movw %ax, %cx - DATA32 call real_to_prot + REAL_TO_PROT .code32 movzwl %cx, %eax @@ -506,3 +180,11 @@ FUNCTION(grub_pxe_call) ret #include "../int.S" + + .bss +VARIABLE(grub_boot_drive) + .byte 0 +VARIABLE(grub_install_dos_part) + .long 0xFFFFFFFF +VARIABLE(grub_install_bsd_part) + .long 0xFFFFFFFF diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 3e8a13892..2e16847c8 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -51,6 +51,14 @@ protstack: .long GRUB_MEMORY_MACHINE_PROT_STACK + .macro PROT_TO_REAL + call prot_to_real + .endm + + .macro REAL_TO_PROT + DATA32 call real_to_prot + .endm + /* * This is the Global Descriptor Table * @@ -162,6 +170,25 @@ protcseg: /* return on the old (or initialized) stack! */ ret +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include prot_to_real: /* just in case, set GDT */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 92354f700..e3b9a377c 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -19,11 +19,11 @@ #ifndef OFFSETS_HEADER #define OFFSETS_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE 0x08 /* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x0c +#define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c /* The offset of GRUB_INSTALL_DOS_PART. */ #define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 @@ -34,15 +34,12 @@ /* Offset of reed_solomon_redundancy. */ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc70 - #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 -#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000 /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 @@ -62,7 +59,6 @@ #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 -#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 @@ -133,10 +129,12 @@ #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE) #define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART) #define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART) #define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR) + +#define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) +#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) #endif #ifndef ASM_FILE diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9369fba3d..9da72f6c9 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -54,7 +54,7 @@ #define TARGET_NO_FIELD 0xffffffff typedef enum { - COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ + COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ, COMPRESSION_LZMA } grub_compression_t; struct image_target_desc @@ -73,13 +73,13 @@ struct image_target_desc enum { PLATFORM_FLAGS_NONE = 0, - PLATFORM_FLAGS_LZMA = 1, PLATFORM_FLAGS_DECOMPRESSORS = 2, PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, } flags; - unsigned raw_size; unsigned total_module_size; - unsigned compressed_size; + unsigned decompressor_compressed_size; + unsigned decompressor_uncompressed_size; + unsigned decompressor_uncompressed_addr; unsigned link_align; grub_uint16_t elf_target; unsigned section_align; @@ -107,9 +107,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -127,9 +128,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -146,10 +148,11 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC, - .flags = PLATFORM_FLAGS_LZMA, - .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, - .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, @@ -162,10 +165,11 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC_PXE, - .flags = PLATFORM_FLAGS_LZMA, - .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, - .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, @@ -179,9 +183,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE @@ -201,9 +206,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -221,9 +227,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -237,9 +244,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, @@ -254,9 +262,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -273,9 +282,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -294,9 +304,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -313,9 +324,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -333,9 +345,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, - .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -349,9 +362,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -365,9 +379,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, @@ -383,9 +398,10 @@ struct image_target_desc image_targets[] = .id = IMAGE_MIPS_ARC, .flags = (PLATFORM_FLAGS_DECOMPRESSORS | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -402,9 +418,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -421,9 +438,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -440,9 +458,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -459,9 +478,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -593,7 +613,7 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static void compress_kernel_lzma (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size, size_t raw_size) + char **core_img, size_t *core_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -606,27 +626,21 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < raw_size) - grub_util_error (_("the core image is too small")); - *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - raw_size; - if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, - (unsigned char *) kernel_img + raw_size, - kernel_size - raw_size, + *core_size = kernel_size; + if (LzmaEncode ((unsigned char *) *core_img, core_size, + (unsigned char *) kernel_img, + kernel_size, &props, out_props, &out_props_size, 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) grub_util_error (_("cannot compress the kernel image")); - - *core_size += raw_size; } #ifdef HAVE_LIBLZMA static void compress_kernel_xz (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size, size_t raw_size) + char **core_img, size_t *core_size) { lzma_stream strm = LZMA_STREAM_INIT; lzma_ret xzret; @@ -647,20 +661,16 @@ compress_kernel_xz (char *kernel_img, size_t kernel_size, { .id = LZMA_VLI_UNKNOWN, .options = NULL} }; - if (kernel_size < raw_size) - grub_util_error (_("the core image is too small")); - xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); if (xzret != LZMA_OK) grub_util_error (_("cannot compress the kernel image")); *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - raw_size; - strm.next_in = (unsigned char *) kernel_img + raw_size; - strm.avail_in = kernel_size - raw_size; - strm.next_out = (unsigned char *) *core_img + raw_size; + *core_size = kernel_size; + strm.next_in = (unsigned char *) kernel_img; + strm.avail_in = kernel_size; + strm.next_out = (unsigned char *) *core_img; strm.avail_out = *core_size; while (1) @@ -674,8 +684,6 @@ compress_kernel_xz (char *kernel_img, size_t kernel_size, } *core_size -= strm.avail_out; - - *core_size += raw_size; } #endif @@ -684,19 +692,20 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, size_t kernel_size, char **core_img, size_t *core_size, grub_compression_t comp) { - if (image_target->flags & PLATFORM_FLAGS_LZMA) - { - compress_kernel_lzma (kernel_img, kernel_size, core_img, - core_size, image_target->raw_size); - return; - } + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == COMPRESSION_LZMA)) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size); + return; + } #ifdef HAVE_LIBLZMA if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS && (comp == COMPRESSION_XZ)) { compress_kernel_xz (kernel_img, kernel_size, core_img, - core_size, image_target->raw_size); + core_size); return; } #endif @@ -747,6 +756,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (comp == COMPRESSION_AUTO) comp = image_target->default_compression; + if (image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE) + comp = COMPRESSION_LZMA; + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -903,31 +916,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], &core_img, &core_size, comp); free (kernel_img); - if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) - kernel_img = core_img + total_module_size; - else - kernel_img = core_img; - grub_util_info ("the core size is 0x%x", core_size); if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) && image_target->total_module_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) = grub_host_to_target32 (total_module_size); - if (image_target->compressed_size != TARGET_NO_FIELD) - *((grub_uint32_t *) (kernel_img + image_target->compressed_size)) - = grub_host_to_target32 (core_size - image_target->raw_size); - - /* If we included a drive in our prefix, let GRUB know it doesn't have to - prepend the drive told by BIOS. */ - if (image_target->install_dos_part != TARGET_NO_FIELD - && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') - { - *((grub_int32_t *) (kernel_img + image_target->install_dos_part)) - = grub_host_to_target32 (-2); - *((grub_int32_t *) (kernel_img + image_target->install_bsd_part)) - = grub_host_to_target32 (-2); - } if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) { @@ -941,6 +935,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], case COMPRESSION_XZ: name = "xz_decompress.img"; break; + case COMPRESSION_LZMA: + name = "lzma_decompress.img"; + break; case COMPRESSION_NONE: name = "none_decompress.img"; break; @@ -952,19 +949,30 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], decompress_size = grub_util_get_image_size (decompress_path); decompress_img = grub_util_read_image (decompress_path); - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size); + if ((image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE) + && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) + grub_util_error (_("Decompressor is too big")); - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE)) - = grub_host_to_target32 (kernel_size + total_module_size); + if (image_target->decompressor_compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_compressed_size)) + = grub_host_to_target32 (core_size); - if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR)) - = grub_host_to_target_addr (image_target->link_addr - total_module_size); - else - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR)) - = grub_host_to_target_addr (image_target->link_addr); + if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_uncompressed_size)) + = grub_host_to_target32 (kernel_size + total_module_size); + if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD) + { + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr - total_module_size); + else + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr); + } full_size = core_size + decompress_size; full_img = xmalloc (full_size); @@ -982,6 +990,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = full_size; } + /* If we included a drive in our prefix, let GRUB know it doesn't have to + prepend the drive told by BIOS. */ + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') + { + *((grub_int32_t *) (core_img + image_target->install_dos_part)) + = grub_host_to_target32 (-2); + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) + = grub_host_to_target32 (-2); + } + switch (image_target->id) { case IMAGE_I386_PC: @@ -1249,7 +1268,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], rom_img = xmalloc (rom_size); memset (rom_img, 0, rom_size); - *((grub_int32_t *) (kernel_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) = grub_host_to_target32 ((grub_uint32_t) -rom_size); memcpy (rom_img, core_img, core_size); From 691cbb58163628d7244b66997e713f443b8af8e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 20:53:46 +0100 Subject: [PATCH 217/315] Fix bug introduced by previous commit. * grub-core/boot/i386/pc/startup_raw.S: Compute RS start correctly. --- ChangeLog | 6 ++++++ grub-core/boot/i386/pc/startup_raw.S | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eeb9bda57..70db75379 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-12 Vladimir Serbinenko + + Fix bug introduced by previous commit. + + * grub-core/boot/i386/pc/startup_raw.S: Compute RS start correctly. + 2011-11-12 Vladimir Serbinenko Use decompressors framework on i386-pc. It increases core size diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 4820e3442..09b6fed76 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -107,7 +107,7 @@ LOCAL (codestart): call grub_gate_a20 movl LOCAL(compressed_size), %edx - addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx + addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - _start), %edx movl reed_solomon_redundancy, %ecx leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax call EXT_C (grub_reed_solomon_recover) From 5fbdac149b05ce50a3de0dfb6ef6d37e29bc8575 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:12:52 +0100 Subject: [PATCH 218/315] Defer multiboot device parsing until we're in compressed part. * grub-core/boot/i386/pc/lnxboot.S: Remove setting dos_part and bsd_part. setdevice has fallen into disuse. * grub-core/boot/i386/pc/startup_raw.S (dos_part): Removed. (bsd_part): Likewise. (boot_dev): New variable. (multiboot_trampoline): Don't parse multiboot device. Pass multiboot device in %edx. * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Parse grub_boot_device. * grub-core/kern/i386/pc/init.c (grub_machine_get_bootlocation): Likewise. * grub-core/kern/i386/pc/startup.S: Save edx. (grub_boot_drive): Removed. (grub_install_dos_part): Likewise. (grub_install_bsd_part): Likewise. (grub_boot_device): New variable. * include/grub/i386/pc/kernel.h (grub_install_dos_part): Removed. (grub_install_bsd_part): Likewise. (grub_boot_drive): Likewise. (grub_boot_device): New variable. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Removed. (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Moved lower. (GRUB_KERNEL_MACHINE_INSTALL_BSD_PART): Removed. (GRUB_KERNEL_MACHINE_INSTALL_DOS_PART): Likewise. * util/grub-install.in: Remove redundant condition. --- ChangeLog | 32 +++++++++++++++++ grub-core/boot/i386/pc/lnxboot.S | 5 --- grub-core/boot/i386/pc/startup_raw.S | 33 +++--------------- grub-core/disk/i386/pc/biosdisk.c | 14 ++++---- grub-core/kern/i386/pc/init.c | 19 ++++++---- grub-core/kern/i386/pc/startup.S | 14 ++------ include/grub/i386/pc/kernel.h | 9 +---- include/grub/offsets.h | 10 +----- util/grub-install.in | 2 +- util/grub-mkimage.c | 52 ---------------------------- util/grub-setup.c | 44 ----------------------- 11 files changed, 63 insertions(+), 171 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70db75379..b5124c18a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2011-11-12 Vladimir Serbinenko + + Defer multiboot device parsing until we're in compressed part. + + * grub-core/boot/i386/pc/lnxboot.S: Remove setting dos_part and + bsd_part. setdevice has fallen into disuse. + * grub-core/boot/i386/pc/startup_raw.S (dos_part): Removed. + (bsd_part): Likewise. + (boot_dev): New variable. + (multiboot_trampoline): Don't parse multiboot device. + Pass multiboot device in %edx. + * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Parse + grub_boot_device. + * grub-core/kern/i386/pc/init.c (grub_machine_get_bootlocation): + Likewise. + * grub-core/kern/i386/pc/startup.S: Save edx. + (grub_boot_drive): Removed. + (grub_install_dos_part): Likewise. + (grub_install_bsd_part): Likewise. + (grub_boot_device): New variable. + * include/grub/i386/pc/kernel.h (grub_install_dos_part): Removed. + (grub_install_bsd_part): Likewise. + (grub_boot_drive): Likewise. + (grub_boot_device): New variable. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): + Removed. + (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. + (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Moved lower. + (GRUB_KERNEL_MACHINE_INSTALL_BSD_PART): Removed. + (GRUB_KERNEL_MACHINE_INSTALL_DOS_PART): Likewise. + * util/grub-install.in: Remove redundant condition. + 2011-11-12 Vladimir Serbinenko Fix bug introduced by previous commit. diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index e5227d174..4fe0df139 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -205,11 +205,6 @@ real_code_2: 2: call LOCAL(move_memory) - movsbl %dh, %eax - movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) - movsbl (reg_edx + 2 - start), %eax - movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) - movb $0xFF, %dh ljmp $(DATA_ADDR >> 4), $0 diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 09b6fed76..9e0f23d71 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -57,13 +57,6 @@ LOCAL(compressed_size): LOCAL(uncompressed_size): .long 0 - . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART -LOCAL(dos_part): - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART -LOCAL(bsd_part): - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY reed_solomon_redundancy: .long 0 @@ -72,8 +65,10 @@ reed_solomon_redundancy: * This is the area for all of the special variables. */ +LOCAL(boot_dev): + .byte 0xFF, 0xFF, 0xFF LOCAL(boot_drive): - .byte 0 + .byte 0x00 /* the real mode code continues... */ LOCAL (codestart): @@ -164,28 +159,12 @@ multiboot_entry: multiboot_trampoline: /* fill the boot information */ - movl %edx, %eax - shrl $8, %eax - xorl %ebx, %ebx - cmpb $0xFF, %ah - je 1f - movb %ah, %bl - movl %ebx, LOCAL(dos_part) -1: - cmpb $0xFF, %al - je 2f - movb %al, %bl - movl %ebx, LOCAL(bsd_part) -2: + movl %edx, LOCAL(boot_dev) shrl $24, %edx - movb %dl, LOCAL(boot_drive) - movb $0xFF, %dh - movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp /* enter the usual booting */ call prot_to_real .code16 jmp LOCAL (codestart) - .code32 post_reed_solomon: @@ -201,9 +180,7 @@ post_reed_solomon: popl %esi #endif - movb LOCAL(boot_drive), %dl - movl LOCAL(dos_part), %eax - movl LOCAL(bsd_part), %ebx + movl LOCAL(boot_dev), %edx movl $prot_to_real, %edi movl $real_to_prot, %ecx jmp *%esi diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 25f683fd1..173e734d8 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -622,7 +622,8 @@ grub_disk_biosdisk_fini (void) GRUB_MOD_INIT(biosdisk) { struct grub_biosdisk_cdrp *cdrp - = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_uint8_t boot_drive; if (grub_disk_firmware_is_tainted) { @@ -634,15 +635,16 @@ GRUB_MOD_INIT(biosdisk) grub_memset (cdrp, 0, sizeof (*cdrp)); cdrp->size = sizeof (*cdrp); cdrp->media_type = 0xFF; - if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) && - ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) - == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) + boot_drive = (grub_boot_device >> 24); + if ((! grub_biosdisk_get_cdinfo_int13_extensions (boot_drive, cdrp)) + && ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) + == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) cd_drive = cdrp->drive_no; /* Since diskboot.S rejects devices over 0x90 it must be a CD booted with cdboot.S */ - if (grub_boot_drive >= 0x90) - cd_drive = grub_boot_drive; + if (boot_drive >= 0x90) + cd_drive = boot_drive; grub_disk_dev_register (&grub_biosdisk_dev); } diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index da7230c33..c6492619f 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -67,10 +67,15 @@ void grub_machine_get_bootlocation (char **device, char **path) { char *ptr; + grub_uint8_t boot_drive, dos_part, bsd_part; + + boot_drive = (grub_boot_device >> 24); + dos_part = (grub_boot_device >> 16); + bsd_part = (grub_boot_device >> 8); /* No hardcoded root partition - make it from the boot drive and the partition number encoded at the install time. */ - if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) + if (boot_drive == GRUB_BOOT_MACHINE_PXE_DL) { if (grub_pc_net_config) grub_pc_net_config (device, path); @@ -82,18 +87,18 @@ grub_machine_get_bootlocation (char **device, char **path) *device = grub_malloc (DEV_SIZE); ptr = *device; grub_snprintf (*device, DEV_SIZE, - "%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', - grub_boot_drive & 0x7f); + "%cd%u", (boot_drive & 0x80) ? 'h' : 'f', + boot_drive & 0x7f); ptr += grub_strlen (ptr); - if (grub_install_dos_part >= 0) + if (dos_part != 0xff) grub_snprintf (ptr, DEV_SIZE - (ptr - *device), - ",%u", grub_install_dos_part + 1); + ",%u", dos_part + 1); ptr += grub_strlen (ptr); - if (grub_install_bsd_part >= 0) + if (bsd_part != 0xff) grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u", - grub_install_bsd_part + 1); + bsd_part + 1); ptr += grub_strlen (ptr); *ptr = 0; } diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 058f9efa7..51e19b7f0 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -82,8 +82,6 @@ LOCAL(cont): movsb #endif - movl %eax, %esi - /* clean out the bss */ movl $BSS_START_SYMBOL, %edi @@ -97,9 +95,7 @@ LOCAL(cont): rep stosb - movl %esi, EXT_C(grub_install_dos_part) - movb %dl, EXT_C(grub_boot_drive) - movl %ebx, EXT_C(grub_install_bsd_part) + movl %edx, EXT_C(grub_boot_device) /* * Call the start of main body of C code. @@ -182,9 +178,5 @@ FUNCTION(grub_pxe_call) #include "../int.S" .bss -VARIABLE(grub_boot_drive) - .byte 0 -VARIABLE(grub_install_dos_part) - .long 0xFFFFFFFF -VARIABLE(grub_install_bsd_part) - .long 0xFFFFFFFF +VARIABLE(grub_boot_device) + .long 0 diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 2dcdbb7a6..4f05b74e3 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -32,14 +32,7 @@ /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The DOS partition number of the installed partition. */ -extern grub_int32_t grub_install_dos_part; - -/* The BSD partition number of the installed partition. */ -extern grub_int32_t grub_install_bsd_part; - -/* The boot BIOS drive number. */ -extern grub_uint8_t EXPORT_VAR(grub_boot_drive); +extern grub_uint32_t EXPORT_VAR(grub_boot_device); extern void (*EXPORT_VAR(grub_pc_net_config)) (char **device, char **path); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index e3b9a377c..1269c865d 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -25,14 +25,8 @@ /* The offset of GRUB_COMPRESSED_SIZE. */ #define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x14 - /* Offset of reed_solomon_redundancy. */ -#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 +#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10 #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 @@ -129,8 +123,6 @@ #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART) -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART) #define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR) #define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) diff --git a/util/grub-install.in b/util/grub-install.in index 26a2523f8..ea8699a44 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -564,7 +564,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" - elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ] || [ "x$platform" = xieee1275 ]; then + else # we need to hardcode the partition number in the core image's prefix. if [ x"$grub_partition" = x ]; then prefix_drive="()" diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9da72f6c9..3912ad7b2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -84,7 +84,6 @@ struct image_target_desc grub_uint16_t elf_target; unsigned section_align; signed vaddr_offset; - unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; unsigned mod_gap, mod_align; grub_compression_t default_compression; @@ -113,8 +112,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, .elf_target = EM_386, .link_align = 4, @@ -134,8 +131,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, .elf_target = EM_386, .link_align = 4, @@ -155,8 +150,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, - .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { @@ -172,8 +165,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, - .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { @@ -194,8 +185,6 @@ struct image_target_desc image_targets[] = + sizeof (struct grub_pe32_optional_header) + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT), - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .pe_target = GRUB_PE32_MACHINE_I386, .elf_target = EM_386, }, @@ -212,8 +201,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, .elf_target = EM_386, .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, @@ -233,8 +220,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR }, { @@ -250,8 +235,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .pe_target = GRUB_PE32_MACHINE_X86_64, .elf_target = EM_X86_64, }, @@ -268,8 +251,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -288,8 +269,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -310,8 +289,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -330,8 +307,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, .elf_target = EM_PPC, .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, @@ -351,8 +326,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, { @@ -368,8 +341,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, { @@ -385,8 +356,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .pe_target = GRUB_PE32_MACHINE_IA64, .elf_target = EM_IA_64, }, @@ -404,8 +373,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, @@ -424,8 +391,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, @@ -444,8 +409,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, @@ -464,8 +427,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, @@ -484,8 +445,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, @@ -990,17 +949,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = full_size; } - /* If we included a drive in our prefix, let GRUB know it doesn't have to - prepend the drive told by BIOS. */ - if (image_target->install_dos_part != TARGET_NO_FIELD - && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') - { - *((grub_int32_t *) (core_img + image_target->install_dos_part)) - = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + image_target->install_bsd_part)) - = grub_host_to_target32 (-2); - } - switch (image_target->id) { case IMAGE_I386_PC: diff --git a/util/grub-setup.c b/util/grub-setup.c index f185ed747..055543f2d 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -101,56 +101,12 @@ write_rootdev (char *core_img, grub_device_t root_dev, { #ifdef GRUB_MACHINE_PCBIOS { - grub_int32_t *install_dos_part, *install_bsd_part; - grub_int32_t dos_part, bsd_part; grub_uint8_t *boot_drive; grub_disk_addr_t *kernel_sector; boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); kernel_sector = (grub_disk_addr_t *) (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); - - install_dos_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); - install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); - - /* If we hardcoded drive as part of prefix, we don't want to - override the current setting. */ - if (*install_dos_part != -2) - { - /* Embed information about the installed location. */ - if (root_dev->disk->partition) - { - if (root_dev->disk->partition->parent) - { - if (root_dev->disk->partition->parent->parent) - grub_util_error (_("Installing on doubly nested partitions " - "is not supported")); - dos_part = root_dev->disk->partition->parent->number; - bsd_part = root_dev->disk->partition->number; - } - else - { - dos_part = root_dev->disk->partition->number; - bsd_part = -1; - } - } - else - dos_part = bsd_part = -1; - } - else - { - dos_part = grub_le_to_cpu32 (*install_dos_part); - bsd_part = grub_le_to_cpu32 (*install_bsd_part); - } - - grub_util_info ("dos partition is %d, bsd partition is %d", - dos_part, bsd_part); - - *install_dos_part = grub_cpu_to_le32 (dos_part); - *install_bsd_part = grub_cpu_to_le32 (bsd_part); - /* FIXME: can this be skipped? */ *boot_drive = 0xFF; From aa94b87027857472aba93d6c7e39abaa10103d96 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:38:04 +0100 Subject: [PATCH 219/315] Fix MIPS compilation. * grub-core/boot/mips/startup_raw.S: Use GRUB_DECOMPRESSOR_* * include/grub/offsets.h: Rename decompressor fields from GRUB_KERNEL_* to GRUB_DECOMPRESSOR_*. * util/grub-mkimage.c (image_targets): Use new names. --- ChangeLog | 9 ++++++ grub-core/boot/mips/startup_raw.S | 6 ++-- include/grub/offsets.h | 23 +++++++-------- util/grub-mkimage.c | 48 +++++++++++++++---------------- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5124c18a..15389a335 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-12 Vladimir Serbinenko + + Fix MIPS compilation. + + * grub-core/boot/mips/startup_raw.S: Use GRUB_DECOMPRESSOR_* + * include/grub/offsets.h: Rename decompressor fields from + GRUB_KERNEL_* to GRUB_DECOMPRESSOR_*. + * util/grub-mkimage.c (image_targets): Use new names. + 2011-11-12 Vladimir Serbinenko Defer multiboot device parsing until we're in compressed part. diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index e76926677..bbbc1dbec 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -240,9 +240,9 @@ cmdlinedone: subu $a0, $a0, $t0 addu $a0, $a0, $s0 - lw $a1, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0) - lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) - lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a1, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0) + lw $a2, (GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a3, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 1269c865d..68ed084cb 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -62,26 +62,26 @@ #define GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 +#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR 0x80200000 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 +#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8bd00000 #define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 +#define GRUB_DECOMPRESSOR_MIPS_ARC_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 @@ -116,10 +116,6 @@ #define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_ALIGN) #define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_GAP) #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _TOTAL_MODULE_SIZE) -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _KERNEL_IMAGE_SIZE) -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _COMPRESSED_SIZE) -#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) -#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) @@ -127,6 +123,7 @@ #define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) #define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) +#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) #endif #ifndef ASM_FILE diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 3912ad7b2..0ffeb909e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -246,9 +246,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -264,9 +264,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -284,9 +284,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -368,9 +368,9 @@ struct image_target_desc image_targets[] = .flags = (PLATFORM_FLAGS_DECOMPRESSORS | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, @@ -386,9 +386,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -404,9 +404,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -422,9 +422,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -440,9 +440,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, From ba102053ce9943a7cf77e9d85f95d5f4bfa8ae1c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:46:52 +0100 Subject: [PATCH 220/315] Support ZFS embedding. * grub-core/fs/zfs/zfs.c (grub_zfs_embed): New function. (grub_zfs_fs): Register grub_zfs_embed. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfs.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/ChangeLog b/ChangeLog index 15389a335..c12f19951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-12 Vladimir Serbinenko + + Support ZFS embedding. + + * grub-core/fs/zfs/zfs.c (grub_zfs_embed): New function. + (grub_zfs_fs): Register grub_zfs_embed. + 2011-11-12 Vladimir Serbinenko Fix MIPS compilation. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 20cba3509..83a067237 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -3806,6 +3806,35 @@ grub_zfs_dir (grub_device_t device, const char *path, return grub_errno; } +#ifdef GRUB_UTIL +static grub_err_t +grub_zfs_embed (grub_device_t device __attribute__ ((unused)), + unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + unsigned i; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ZFS currently supports only PC-BIOS embedding"); + + if ((VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS) < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your core.img is unusually large. " + "It won't fit in the embedding area."); + + *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = i + (VDEV_BOOT_OFFSET >> GRUB_DISK_SECTOR_BITS); + + return GRUB_ERR_NONE; +} +#endif + static struct grub_fs grub_zfs_fs = { .name = "zfs", .dir = grub_zfs_dir, @@ -3815,6 +3844,10 @@ static struct grub_fs grub_zfs_fs = { .label = zfs_label, .uuid = zfs_uuid, .mtime = zfs_mtime, +#ifdef GRUB_UTIL + .embed = grub_zfs_embed, + .reserved_first_sector = 1, +#endif .next = 0 }; From 9edd7be26aef4fe4293835bb9dce3f49e7aff007 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:14:51 +0100 Subject: [PATCH 221/315] Fix spaces handling in proc/self/mountinfo. * util/getroot.c (unescape): New function. (grub_find_root_device_from_mountinfo): Use unescape. --- ChangeLog | 7 +++++++ util/getroot.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/ChangeLog b/ChangeLog index c12f19951..ab253ddfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-12 Vladimir Serbinenko + + Fix spaces handling in proc/self/mountinfo. + + * util/getroot.c (unescape): New function. + (grub_find_root_device_from_mountinfo): Use unescape. + 2011-11-12 Vladimir Serbinenko Support ZFS embedding. diff --git a/util/getroot.c b/util/getroot.c index f5d6d3f62..96879f545 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -129,6 +129,27 @@ struct mountinfo_entry can't deal with the multiple-device case yet, but in the meantime, we can at least cope with the single-device case by scanning /proc/self/mountinfo. */ +static void +unescape (char *str) +{ + char *optr; + const char *iptr; + for (iptr = optr = str; *iptr; optr++) + { + if (iptr[0] == '\\' && iptr[1] >= '0' && iptr[1] < '8' + && iptr[2] >= '0' && iptr[2] < '8' + && iptr[3] >= '0' && iptr[3] < '8') + { + *optr = (((iptr[1] - '0') << 6) | ((iptr[2] - '0') << 3) + | (iptr[3] - '0')); + iptr += 4; + } + else + *optr = *iptr++; + } + *optr = 0; +} + char * grub_find_root_device_from_mountinfo (const char *dir, char **relroot) { @@ -165,6 +186,9 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) entry.enc_root, entry.enc_path, &count) < 6) continue; + unescape (entry.enc_root); + unescape (entry.enc_path); + enc_path_len = strlen (entry.enc_path); /* Check that enc_path is a prefix of dir. The prefix must either be the entire string, or end with a slash, or be immediately followed From 0cddeb0360d60b518b721996d0dd5d0e5eff476a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:16:48 +0100 Subject: [PATCH 222/315] Add copyright year. --- grub-core/disk/lvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 388c7f173..2fd736439 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -1,7 +1,7 @@ /* lvm.c - module to read Logical Volumes. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,2009,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 From 91e5a33da510d7e48e35c76f54f8ff3b53c19c0e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:35:20 +0100 Subject: [PATCH 223/315] * include/grub/lvm.h (grub_lvm_pv): Correct start type. --- ChangeLog | 4 ++++ include/grub/lvm.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab253ddfd..9f5b71fe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * include/grub/lvm.h (grub_lvm_pv): Correct start type. + 2011-11-12 Vladimir Serbinenko Fix spaces handling in proc/self/mountinfo. diff --git a/include/grub/lvm.h b/include/grub/lvm.h index b5352c75c..d77b88ff5 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -38,7 +38,7 @@ struct grub_lvm_pv { char id[GRUB_LVM_ID_STRLEN+1]; char *name; grub_disk_t disk; - int start; /* Sector number where the data area starts. */ + grub_disk_addr_t start; /* Sector number where the data area starts. */ struct grub_lvm_pv *next; }; From 91ee7b6d737fdba31e052fbe44349d94895df99f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:42:49 +0100 Subject: [PATCH 224/315] * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. --- ChangeLog | 4 ++++ grub-core/kern/emu/hostdisk.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9f5b71fe4..1ce25663d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. + 2011-11-12 Vladimir Serbinenko * include/grub/lvm.h (grub_lvm_pv): Correct start type. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index f537b2759..ede765d83 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1751,7 +1751,10 @@ find_system_device (const char *os_dev, struct stat *st, int convert, int add) } if (!add) - return -1; + { + free (os_disk); + return -1; + } if (i == ARRAY_SIZE (map)) grub_util_error (_("device count exceeds limit")); From d89ee4141a1bc3ad1dd5bdacedbd2a2b2409f09b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:46:47 +0100 Subject: [PATCH 225/315] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Fix a memory leak. (grub_util_biosdisk_get_grub_dev): Add a useful debug info. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ce25663d..230eb0cec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): + Fix a memory leak. + (grub_util_biosdisk_get_grub_dev): Add a useful debug info. + 2011-11-12 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index ede765d83..da2cc6aa2 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1781,6 +1781,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { struct stat st; int drive; + char *sys_disk; grub_util_info ("Looking for %s", os_dev); @@ -1800,9 +1801,13 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, - convert_system_partition_to_system_disk (os_dev, &st)) == 0) - return make_device_name (drive, -1, -1); + sys_disk = convert_system_partition_to_system_disk (os_dev, &st); + if (grub_strcmp (os_dev, sys_disk) == 0) + { + free (sys_disk); + return make_device_name (drive, -1, -1); + } + free (sys_disk); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) @@ -1914,6 +1919,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (partname == NULL) { grub_disk_close (disk); + grub_util_info ("cannot find the partition of `%s'", os_dev); grub_error (GRUB_ERR_BAD_DEVICE, "cannot find the partition of `%s'", os_dev); return 0; From a346b81c7d9e3c0ebca495f6b4f0bc49baa72712 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 00:01:06 +0100 Subject: [PATCH 226/315] * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore disk->partiton for safety. --- ChangeLog | 5 +++++ grub-core/partmap/gpt.c | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 230eb0cec..95aed126c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore + disk->partiton for safety. + 2011-11-12 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 73a1c3b19..c8bc52609 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -140,11 +140,17 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, const grub_partition_t p) { struct grub_gpt_partentry gptdata; + grub_partition_t p2; + p2 = disk->partition; disk->partition = p->parent; if (grub_disk_read (disk, p->offset, p->index, sizeof (gptdata), &gptdata)) - return 0; + { + disk->partition = p2; + return 0; + } + disk->partition = p2; /* If there's an embed region, it is in a dedicated partition. */ if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) From fa5aeffcc279dc7ac6a6c75c7151651c87d02322 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 00:07:08 +0100 Subject: [PATCH 227/315] * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. --- ChangeLog | 4 ++++ grub-core/partmap/gpt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 95aed126c..623313b3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. + 2011-11-12 Vladimir Serbinenko * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index c8bc52609..049fda850 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -165,7 +165,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (embed_type != GRUB_EMBED_PCBIOS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "GPT curently supports only PC-BIOS embedding"); + "GPT currently supports only PC-BIOS embedding"); err = gpt_partition_map_iterate (disk, find_usable_region); if (err) From 383ceaf0609040610c7ebc8279d958971ca96084 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 12:52:21 +0100 Subject: [PATCH 228/315] Fix a mismerge --- grub-core/loader/i386/pc/plan9.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 73d4eed38..6e49a34b6 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -78,8 +78,7 @@ grub_plan9_boot (void) .edi = 0, .esp = 0, .ebp = 0, - .esi = 0, - .a20 = 1 + .esi = 0 }; grub_video_set_mode ("text", 0, 0); From c30be3b694dbc95c38df9212d1f01b68c8ecdd26 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 14:48:19 +0100 Subject: [PATCH 229/315] Make Reed-Solomon faster by using power of generator representation of GF(256)*. * grub-core/lib/reed_solomon.c (grub_uint16_t) [TEST]: Removed. (gf_double_t): Likewise. (gf_invert): Removed. (gf_powx): New array. (gf_powx_inv): Likewise. (scratch): Move higher. (gf_reduce): Removed. (gf_mul): Use powx. (gf_invert): Likewise. (init_inverts): Replaced with ... (init_powx): ...this. All users updated. (pol_evaluate): Replace multiplications with additions. (rs_encode): Likewise. (gauss_eliminate): Call gf_invert. (grub_reed_solomon_add_redundancy): Call init_powx. (grub_reed_solomon_recover): Call init_powx unconditionally. --- ChangeLog | 22 ++++++++ grub-core/lib/reed_solomon.c | 105 +++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 623313b3c..229567014 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2011-11-13 Vladimir Serbinenko + + Make Reed-Solomon faster by using power of generator representation of + GF(256)*. + + * grub-core/lib/reed_solomon.c (grub_uint16_t) [TEST]: Removed. + (gf_double_t): Likewise. + (gf_invert): Removed. + (gf_powx): New array. + (gf_powx_inv): Likewise. + (scratch): Move higher. + (gf_reduce): Removed. + (gf_mul): Use powx. + (gf_invert): Likewise. + (init_inverts): Replaced with ... + (init_powx): ...this. All users updated. + (pol_evaluate): Replace multiplications with additions. + (rs_encode): Likewise. + (gauss_eliminate): Call gf_invert. + (grub_reed_solomon_add_redundancy): Call init_powx. + (grub_reed_solomon_recover): Call init_powx unconditionally. + 2011-11-12 Vladimir Serbinenko * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 78d249c2f..7da5f204c 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -29,7 +29,6 @@ #ifdef TEST typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; -typedef unsigned short grub_uint16_t; #else #include #include @@ -42,7 +41,6 @@ typedef unsigned short grub_uint16_t; #ifdef TEST typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; -typedef unsigned short grub_uint16_t; #else #include #include @@ -53,65 +51,72 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs); #define GF_SIZE 8 typedef grub_uint8_t gf_single_t; -typedef grub_uint16_t gf_double_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e #if defined (STANDALONE) && !defined (TEST) -static gf_single_t * const gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; -static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; +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_invert[256]; +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_reduce (gf_double_t a) -{ - int i; - for (i = GF_SIZE - 1; i >= 0; i--) - if (a & (1ULL << (i + GF_SIZE))) - a ^= (((gf_double_t) GF_POLYNOMIAL) << i); - return a & ((1ULL << GF_SIZE) - 1); -} - static gf_single_t gf_mul (gf_single_t a, gf_single_t b) { - gf_double_t res = 0; - int i; - for (i = 0; i < GF_SIZE; i++) - if (b & (1 << i)) - res ^= ((gf_double_t) a) << i; - return gf_reduce (res); + 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_inverts (void) +init_powx (void) { - gf_single_t a = 1, ai = 1; - do + int i; + grub_uint8_t cur = 1; + + for (i = 0; i < 255; i++) { - a = gf_mul (a, 2); - ai = gf_mul (ai, GF_INVERT2); - gf_invert[a] = ai; + 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; } - while (a != 1); } static gf_single_t pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) { int i; - gf_single_t xn = 1, s = 0; + 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--) { - s ^= gf_mul (pol[i], xn); - xn = gf_mul (x, xn); + 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; } @@ -120,7 +125,7 @@ pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) static void rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) { - gf_single_t *rs_polynomial, a = 1; + gf_single_t *rs_polynomial; int i, j; gf_single_t *m; m = xmalloc ((s + rs) * sizeof (gf_single_t)); @@ -132,16 +137,14 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) /* Multiply with X - a^r */ for (j = 0; j < rs; j++) { - if (a & (1 << (GF_SIZE - 1))) - { - a <<= 1; - a ^= GF_POLYNOMIAL; - } - else - a <<= 1; for (i = 0; i < rs; i++) - rs_polynomial[i] = rs_polynomial[i + 1] ^ gf_mul (a, rs_polynomial[i]); - rs_polynomial[rs] = gf_mul (a, rs_polynomial[rs]); + 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]) @@ -190,7 +193,7 @@ gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen) if (nzidx == m) continue; chosen[i] = nzidx; - r = gf_invert [eq[i * (m + 1) + 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++) @@ -437,6 +440,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, if (!rs) return; + init_powx (); + while (s > 0) { grub_size_t tt; @@ -468,9 +473,7 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) if (!rs) return; -#if defined (STANDALONE) - init_inverts (); -#endif + init_powx (); while (s > 0) { @@ -500,12 +503,15 @@ main (int argc, char **argv) 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_inverts (); + init_powx (); #endif in = fopen ("tst.bin", "rb"); @@ -514,7 +520,7 @@ main (int argc, char **argv) fseek (in, 0, SEEK_END); s = ftell (in); fseek (in, 0, SEEK_SET); - rs = s / 3; + rs = 0x7007; buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s, in); fclose (in); @@ -524,8 +530,9 @@ main (int argc, char **argv) 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); From bc108a4a8a4d20dd122cee786befc99bcbe48735 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 19:53:12 +0100 Subject: [PATCH 230/315] * util/grub-mount.c (argp_parser): Accept relative pathes. * util/grub-fstest.c (argp_parser): Likewise. --- ChangeLog | 5 +++++ util/grub-fstest.c | 7 +------ util/grub-mount.c | 7 +------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c3ccb631..d3c48339e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-13 Vladimir Serbinenko + + * util/grub-mount.c (argp_parser): Accept relative pathes. + * util/grub-fstest.c (argp_parser): Likewise. + 2011-11-13 Vladimir Serbinenko Plan9 support. diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c9f24ff08..886155fe2 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -562,14 +562,9 @@ argp_parser (int key, char *arg, struct argp_state *state) if (args_count < num_disks) { - if (arg[0] != '/') - { - fprintf (stderr, "%s", _("Must use absolute path.\n")); - argp_usage (state); - } if (args_count == 0) images = xmalloc (num_disks * sizeof (images[0])); - images[args_count] = xstrdup (arg); + images[args_count] = canonicalize_file_name (arg); args_count++; return 0; } diff --git a/util/grub-mount.c b/util/grub-mount.c index a4be21738..da7d604a2 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -489,13 +489,8 @@ argp_parser (int key, char *arg, struct argp_state *state) return 0; } - if (arg[0] != '/') - { - fprintf (stderr, "%s", _("Must use absolute path.\n")); - argp_usage (state); - } images = xrealloc (images, (num_disks + 1) * sizeof (images[0])); - images[num_disks] = xstrdup (arg); + images[num_disks] = canonicalize_file_name (arg); num_disks++; return 0; From 2536cf64633e7334d1c04bc865907feee5128fdb Mon Sep 17 00:00:00 2001 From: Lubomir Kundrak Date: Sun, 13 Nov 2011 22:59:46 +0100 Subject: [PATCH 231/315] Add facility to debug GRUB with gdb under qemu. * grub-core/gdb_grub.in: New file. * grub-core/gmodule.pl.in: Likewise. * grub-core/Makefile.core.def (gmodule.pl): New script. (gdb_grub): Likewise. --- ChangeLog | 9 ++++ grub-core/Makefile.core.def | 12 ++++++ grub-core/gdb_grub.in | 82 +++++++++++++++++++++++++++++++++++++ grub-core/gmodule.pl.in | 30 ++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 grub-core/gdb_grub.in create mode 100644 grub-core/gmodule.pl.in diff --git a/ChangeLog b/ChangeLog index d3c48339e..22421a715 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-13 Lubomir Kundrak + + Add facility to debug GRUB with gdb under qemu. + + * grub-core/gdb_grub.in: New file. + * grub-core/gmodule.pl.in: Likewise. + * grub-core/Makefile.core.def (gmodule.pl): New script. + (gdb_grub): Likewise. + 2011-11-13 Vladimir Serbinenko * util/grub-mount.c (argp_parser): Accept relative pathes. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fc0472d32..cae79b381 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -18,6 +18,18 @@ script = { common = modinfo.sh.in; }; +script = { + installdir = noinst; + name = gmodule.pl; + common = gmodule.pl.in; +}; + +script = { + installdir = noinst; + name = gdb_grub; + common = gdb_grub.in; +}; + kernel = { name = kernel; diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in new file mode 100644 index 000000000..4a55233da --- /dev/null +++ b/grub-core/gdb_grub.in @@ -0,0 +1,82 @@ +### +### Load debuging information about GNU GRUB 2 modules into GDB +### automatically. Needs readelf, Perl and gmodule.pl script +### +### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $ +### Lubomir Kundrak +### + +# Add section numbers and addresses to .segments.tmp +define dump_module_sections + set $mod = $arg0 + + # FIXME: save logging status + set logging file .segments.tmp + set logging redirect on + set logging overwrite off + set logging on + + printf "%s", $mod->name + set $segment = $mod->segment + while ($segment) + printf " %i 0x%x", $segment->section, $segment->addr + set $segment = $segment->next + end + printf "\n" + + set logging off + # FIXME: restore logging status +end +document dump_module_sections + Gather information about module whose mod structure was + given for use with match_and_load_symbols +end + +# Generate and execute GDB commands and delete temporary files +# afterwards +define match_and_load_symbols + shell perl gmodule.pl <.segments.tmp >.loadsym.gdb + source .loadsym.gdb + shell rm -f .segments.tmp .loadsym.gdb +end +document match_and_load_symbols + Launch script, that matches section names with information + generated by dump_module_sections and load debugging info + apropriately +end + +### + +define load_module + dump_module_sections $arg0 + match_and_load_symbols +end +document load_module + Load debugging information for module given as argument. +end + +define load_all_modules + set $this = grub_dl_head + while ($this != 0) + dump_module_sections $this->mod + set $this = $this->next + end + match_and_load_symbols +end +document load_all_modules + Load debugging information for all loaded modules. +end + +### + +set confirm off +file kernel.exec +target remote :1234 + +# inform when module is loaded +break grub_dl_add +commands + silent + load_module mod + cont +end diff --git a/grub-core/gmodule.pl.in b/grub-core/gmodule.pl.in new file mode 100644 index 000000000..6739a6f1c --- /dev/null +++ b/grub-core/gmodule.pl.in @@ -0,0 +1,30 @@ +### +### Generate GDB commands, that load symbols for specified module, +### with proper section relocations. See .gdbinit +### +### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $ +### Lubomir Kundrak +### + +use strict; + +while (<>) { + my ($name, %sections) = split; + + print "add-symbol-file $name.module"; + + open (READELF, "readelf -S $name.mod |") or die; + while () { + /\[\s*(\d+)\]\s+(\.\S+)/ or next; + + if ($2 eq '.text') { + print " $sections{$1}"; + next; + } + + print " -s $2 $sections{$1}" + if ($sections{$1} ne '0x0'); + }; + close (READELF); + print "\n"; +} From 581ffa8a24d8c7db638ee2e0e812f5c30155c7ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 14 Nov 2011 14:25:09 +0100 Subject: [PATCH 232/315] * grub-core/lib/adler32.c: Add missing license specification. * grub-core/lib/crc64.c: Likewise. * grub-core/loader/i386/pc/plan9.c: Likewise. * grub-core/partmap/plan.c: Likewise. --- ChangeLog | 7 +++++++ grub-core/lib/adler32.c | 2 ++ grub-core/lib/crc64.c | 2 ++ grub-core/loader/i386/pc/plan9.c | 2 ++ grub-core/partmap/plan.c | 2 ++ 5 files changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index 22421a715..143a189c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-14 Vladimir Serbinenko + + * grub-core/lib/adler32.c: Add missing license specification. + * grub-core/lib/crc64.c: Likewise. + * grub-core/loader/i386/pc/plan9.c: Likewise. + * grub-core/partmap/plan.c: Likewise. + 2011-11-13 Lubomir Kundrak Add facility to debug GRUB with gdb under qemu. diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c index 6fb0b00f8..2a2464db3 100644 --- a/grub-core/lib/adler32.c +++ b/grub-core/lib/adler32.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Based on adler32() from adler32.c of zlib-1.2.5 library. */ #define BASE 65521UL diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c index 92c398d1e..4b1c92cf0 100644 --- a/grub-core/lib/crc64.c +++ b/grub-core/lib/crc64.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_uint64_t crc64_table [256]; static void diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 7bcd4ff3a..5528b2c9f 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -34,6 +34,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static struct grub_relocator *rel; static grub_uint32_t eip = 0xffffffff; diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c index c62d04b73..e6e311319 100644 --- a/grub-core/partmap/plan.c +++ b/grub-core/partmap/plan.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_partition_map grub_plan_partition_map; static grub_err_t From bdfe9eeb2c0b28eabea0e4b583f26399cceacf33 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Nov 2011 21:35:40 +0100 Subject: [PATCH 233/315] * grub-core/kern/x86_64/efi/callwrap.S: Fix the comment. --- ChangeLog | 4 ++++ grub-core/kern/x86_64/efi/callwrap.S | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 143a189c4..b3fd9bf78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-16 Vladimir Serbinenko + + * grub-core/kern/x86_64/efi/callwrap.S: Fix the comment. + 2011-11-14 Vladimir Serbinenko * grub-core/lib/adler32.c: Add missing license specification. diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index dced859ac..2df95dda1 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -25,7 +25,7 @@ * different call conversion, so we need to do some conversion. * * gcc: - * %rdi, %esi, %rdx, %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ... + * %rdi, %rsi, %rdx, %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ... * * efi: * %rcx, %rdx, %r8, %r9, 32(%rsp), 40(%rsp), 48(%rsp), ... From bb41695449030bee6b5679096ebe3d8f7ddd9a68 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Nov 2011 21:38:00 +0100 Subject: [PATCH 234/315] * grub-core/kern/dl.c (grub_dl_unload): Fix freeing segments. --- ChangeLog | 4 ++++ grub-core/kern/dl.c | 9 +-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3fd9bf78..1c000592f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-16 Vladimir Serbinenko + + * grub-core/kern/dl.c (grub_dl_unload): Fix freeing segments. + 2011-11-16 Vladimir Serbinenko * grub-core/kern/x86_64/efi/callwrap.S: Fix the comment. diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 26cf0d21d..345e80b90 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -729,7 +729,6 @@ int grub_dl_unload (grub_dl_t mod) { grub_dl_dep_t dep, depn; - grub_dl_segment_t seg, segn; if (mod->ref_count > 0) return 0; @@ -749,13 +748,7 @@ grub_dl_unload (grub_dl_t mod) grub_free (dep); } - for (seg = mod->segment; seg; seg = segn) - { - segn = seg->next; - grub_free (seg->addr); - grub_free (seg); - } - + grub_free (mod->base); grub_free (mod->name); #ifdef GRUB_MODULES_MACHINE_READONLY grub_free (mod->symtab); From 10b64f1cf410f5019c105d80913053d13973b9ed Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 16 Nov 2011 21:40:50 +0100 Subject: [PATCH 235/315] * grub-core/kern/dl.c (grub_dl_load_segments): Fix alignment handling. --- ChangeLog | 4 ++++ grub-core/kern/dl.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1c000592f..50d552fcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-16 Vladimir Serbinenko + + * grub-core/kern/dl.c (grub_dl_load_segments): Fix alignment handling. + 2011-11-16 Vladimir Serbinenko * grub-core/kern/dl.c (grub_dl_unload): Fix freeing segments. diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 345e80b90..aaeb01f00 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -243,7 +243,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) i < e->e_shnum; i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) { - tsize += ALIGN_UP (s->sh_size, s->sh_addralign); + tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size; if (talign < s->sh_addralign) talign = s->sh_addralign; } From adac52113dd713a01655ad95ff3924ce3cb31810 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 25 Nov 2011 14:12:05 +0100 Subject: [PATCH 236/315] * grub-core/fs/cpio.c (grub_cpio_dir): Handle subdirs correctly. --- ChangeLog | 4 ++++ grub-core/fs/cpio.c | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 50d552fcf..d75957f57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-25 Vladimir Serbinenko + + * grub-core/fs/cpio.c (grub_cpio_dir): Handle subdirs correctly. + 2011-11-16 Vladimir Serbinenko * grub-core/kern/dl.c (grub_dl_load_segments): Fix alignment handling. diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 39b35b335..63a1d1f43 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -404,13 +404,15 @@ grub_cpio_dir (grub_device_t device, const char *path_in, { struct grub_cpio_data *data; grub_disk_addr_t ofs; - char *prev, *name, *path; + char *prev, *name, *path, *ptr; grub_size_t len; int symlinknest = 0; path = grub_strdup (path_in + 1); if (!path) return grub_errno; + for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--) + *ptr = 0; grub_dl_ref (my_mod); @@ -443,14 +445,14 @@ grub_cpio_dir (grub_device_t device, const char *path_in, char *p, *n; n = name + len; - if (*n == '/') + while (*n == '/') n++; - p = grub_strchr (name + len, '/'); + p = grub_strchr (n, '/'); if (p) *p = 0; - if (((!prev) || (grub_strcmp (prev, name) != 0)) && name[len] != 0) + if (((!prev) || (grub_strcmp (prev, n) != 0)) && *n != 0) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -458,7 +460,7 @@ grub_cpio_dir (grub_device_t device, const char *path_in, info.mtime = mtime; info.mtimeset = 1; - hook (name + len, &info); + hook (n, &info); grub_free (prev); prev = name; } From 78845dc270e72f6f6b542568372b023b4b81b6e2 Mon Sep 17 00:00:00 2001 From: Seth Goldberg Date: Fri, 25 Nov 2011 14:16:44 +0100 Subject: [PATCH 237/315] * po/Makefile.in.in: Add missing escape-continuation. --- ChangeLog | 4 ++++ po/Makefile.in.in | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d75957f57..1b336c942 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-25 Seth Goldberg + + * po/Makefile.in.in: Add missing escape-continuation. + 2011-11-25 Vladimir Serbinenko * grub-core/fs/cpio.c (grub_cpio_dir): Handle subdirs correctly. diff --git a/po/Makefile.in.in b/po/Makefile.in.in index b0e7b8fa2..5a7c07c5b 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -165,7 +165,7 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell --package-version='@VERSION@' \ --msgid-bugs-address="$$msgid_bugs_address" \ ;; \ - esac + esac; \ case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ @@ -187,7 +187,7 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell --join-existing --language=Shell \ --keyword=gettext_quoted --keyword=gettext_printf \ ;; \ - esac + esac ; \ test ! -f $(DOMAIN).po || { \ sed -f grub.d.sed < $(DOMAIN).po > $(DOMAIN).1po && \ mv $(DOMAIN).1po $(DOMAIN).po; \ From fd258e5cce01dcb354b4a01578577542a4ee108f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 25 Nov 2011 23:07:33 +0100 Subject: [PATCH 238/315] 2011-11-25 Robert Millan * util/getroot.c [HAVE_LIMITS_H]: Include `'. (find_root_device_from_libzfs): Add zpool output parser to be used as fallback when libzfs isn't available. --- ChangeLog | 6 ++++ util/getroot.c | 74 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b336c942..cb98ebf0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-25 Robert Millan + + * util/getroot.c [HAVE_LIMITS_H]: Include `'. + (find_root_device_from_libzfs): Add zpool output parser to be used + as fallback when libzfs isn't available. + 2011-11-25 Seth Goldberg * po/Makefile.in.in: Add missing escape-continuation. diff --git a/util/getroot.c b/util/getroot.c index 96879f545..cc3fdf77d 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -32,6 +32,9 @@ #include #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #include #include #include @@ -273,7 +276,6 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) #endif /* __linux__ */ -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) static char * find_root_device_from_libzfs (const char *dir) { @@ -285,6 +287,7 @@ find_root_device_from_libzfs (const char *dir) if (! poolname) return NULL; +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) { zpool_handle_t *zpool; libzfs_handle_t *libzfs; @@ -340,6 +343,61 @@ find_root_device_from_libzfs (const char *dir) zpool_close (zpool); } +#else + { + char *cmd; + FILE *fp; + int ret; + char *line; + size_t len; + int st; + + char name[PATH_MAX], state[256], readlen[256], writelen[256], cksum[256], notes[256]; + unsigned int dummy; + + asprintf (&cmd, "zpool status %s", poolname); + fp = popen (cmd, "r"); + free (cmd); + + st = 0; + while (st < 3) + { + line = NULL; + ret = getline (&line, &len, fp); + if (ret == -1) + goto fail; + + if (sscanf (line, " %s %256s %256s %256s %256s %256s", name, state, readlen, writelen, cksum, notes) >= 5) + switch (st) + { + case 0: + if (!strcmp (name, "NAME") + && !strcmp (state, "STATE") + && !strcmp (readlen, "READ") + && !strcmp (writelen, "WRITE") + && !strcmp (cksum, "CKSUM")) + st++; + break; + case 1: + if (!strcmp (name, poolname)) + st++; + break; + case 2: + if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy) + && !sscanf (name, "raidz%u", &dummy) + && !strcmp (state, "ONLINE")) + st++; + break; + } + + free (line); + } + asprintf (&device, "/dev/%s", name); + + fail: + pclose (fp); + } +#endif free (poolname); if (poolfs) @@ -347,7 +405,6 @@ find_root_device_from_libzfs (const char *dir) return device; } -#endif #ifdef __MINGW32__ @@ -650,10 +707,8 @@ grub_guess_root_device (const char *dir) os_dev = grub_find_root_device_from_mountinfo (dir, NULL); #endif /* __linux__ */ -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) if (!os_dev) os_dev = find_root_device_from_libzfs (dir); -#endif if (os_dev) { @@ -1383,7 +1438,6 @@ grub_get_libzfs_handle (void) } #endif /* HAVE_LIBZFS */ -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* ZFS has similar problems to those of btrfs (see above). */ void grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) @@ -1444,7 +1498,6 @@ grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) else *poolfs = xstrdup (""); } -#endif /* This function never prints trailing slashes (so that its output can be appended a slash unconditionally). */ @@ -1456,23 +1509,18 @@ grub_make_system_path_relative_to_its_root (const char *path) uintptr_t offset = 0; dev_t num; size_t len; - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) char *poolfs = NULL; -#endif /* canonicalize. */ p = canonicalize_file_name (path); if (p == NULL) grub_util_error (_("failed to get canonical path of %s"), path); -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ { char *dummy; grub_find_zpool_from_dir (p, &dummy, &poolfs); } -#endif len = strlen (p) + 1; buf = xstrdup (p); @@ -1524,10 +1572,8 @@ grub_make_system_path_relative_to_its_root (const char *path) } #endif free (buf2); -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) if (poolfs) return xasprintf ("/%s/@", poolfs); -#endif return xstrdup (""); } else @@ -1584,14 +1630,12 @@ grub_make_system_path_relative_to_its_root (const char *path) len--; } -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) if (poolfs) { ret = xasprintf ("/%s/@%s", poolfs, buf3); free (buf3); } else -#endif ret = buf3; return ret; From 49e891ac9ca701513172cf2fec5b9c5c73e89c4f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Nov 2011 02:34:22 +0100 Subject: [PATCH 239/315] * grub-core/fs/zfs/zfs.c (recovery): Fix spelling. (read_device): Fix size calculation. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb98ebf0a..52da3c3a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-27 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (recovery): Fix spelling. + (read_device): Fix size calculation. + 2011-11-25 Robert Millan * util/getroot.c [HAVE_LIMITS_H]: Include `'. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 83a067237..be659f52c 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1001,7 +1001,7 @@ recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, const unsigned *powers, const int *idx) { - grub_dprintf ("zfs", "recovering %u bufers\n", nbufs); + grub_dprintf ("zfs", "recovering %u buffers\n", nbufs); /* Now we have */ /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ /* Let's invert the matrix in question. */ @@ -1338,8 +1338,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, { grub_uint8_t *tmp_recovery_buf[4]; for (j = 0; j < i; j++) - tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[j] - 1; - err = recovery (tmp_recovery_buf, 1, i, redundancy_pow, + tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[failed_devices - 1]; + err = recovery (tmp_recovery_buf, recovery_len[0] - recovery_len[failed_devices - 1], i, redundancy_pow, recovery_idx); if (err) return err; From 112b483765b3e301396bb807b547ee1e1fb2392b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Nov 2011 01:10:00 +0000 Subject: [PATCH 240/315] * util/getroot.c (find_root_device_from_libzfs): Use xasprintf. --- ChangeLog | 4 ++++ util/getroot.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52da3c3a6..07f3fb62c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-28 Colin Watson + + * util/getroot.c (find_root_device_from_libzfs): Use xasprintf. + 2011-11-27 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (recovery): Fix spelling. diff --git a/util/getroot.c b/util/getroot.c index cc3fdf77d..05bee4964 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -355,7 +355,7 @@ find_root_device_from_libzfs (const char *dir) char name[PATH_MAX], state[256], readlen[256], writelen[256], cksum[256], notes[256]; unsigned int dummy; - asprintf (&cmd, "zpool status %s", poolname); + cmd = xasprintf ("zpool status %s", poolname); fp = popen (cmd, "r"); free (cmd); @@ -392,7 +392,7 @@ find_root_device_from_libzfs (const char *dir) free (line); } - asprintf (&device, "/dev/%s", name); + device = xasprintf ("/dev/%s", name); fail: pclose (fp); From bf3a3857928e4647a85386f8975dae7a44bf4f4e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Nov 2011 16:20:13 +0100 Subject: [PATCH 241/315] Add missing const qualifiers. * grub-core/commands/i386/pc/sendkey.c (keysym): Add missing const. * grub-core/commands/lspci.c (grub_pci_classname): Likewise. * grub-core/commands/menuentry.c (hotkey_aliases): Likewise. * grub-core/disk/lvm.c (grub_lvm_getvalue): Likewise. (grub_lvm_check_flag): Likewise. * grub-core/efiemu/i386/coredetect.c (grub_efiemu_get_default_core_name): Likewise * grub-core/efiemu/main.c (grub_efiemu_autocore): Likewise. * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Likewise. * grub-core/fs/ntfs.c (fixup): Likewise. * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Likewise. * grub-core/fs/zfs/zfs.c (decomp_entry): Likewise. (fzap_lookup): Likewise. (zap_lookup): Likewise. * grub-core/gnulib/regcomp.c (init_dfa): Likewise. * grub-core/lib/legacy_parse.c (check_option): Likewise. * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Likewise. * grub-core/loader/i386/bsd.c (grub_bsd_add_meta): Likewise. (grub_freebsd_add_meta_module): Likewise. (grub_cmd_freebsd_module): Likewise. * grub-core/loader/i386/xnu.c (tbl_alias): Likewise. * grub-core/loader/xnu.c (grub_xnu_register_memory): Likewise. (grub_xnu_writetree_get_size): Likewise. (grub_xnu_writetree_toheap_real): Likewise. (grub_xnu_find_key): Likewise. (grub_xnu_create_key): Likewise. (grub_xnu_create_value): Likewise. (grub_xnu_register_memory): Likewise. (grub_xnu_check_os_bundle_required): Likewise. (grub_xnu_scan_dir_for_kexts): Likewise. (grub_xnu_load_kext_from_dir): Likewise. * grub-core/normal/color.c (color_list): Likewise. * grub-core/normal/completion.c (current_word): Likewise. * grub-core/normal/menu_entry.c (insert_string): Likewise. * grub-core/term/serial.c (grub_serial_find): Likewise. * grub-core/term/tparm.c (grub_terminfo_tparm): Likewise. * include/grub/efiemu/efiemu.h (grub_efiemu_get_default_core_name): Likewise. * include/grub/i386/bsd.h (grub_bsd_add_meta): Likewise. (grub_freebsd_add_meta_module): Likewise. * include/grub/lib/arg.h (grub_arg_option): Likewise. * include/grub/net.h (grub_net_card_driver): Likewise. (grub_net_card): Likewise. (grub_net_app_protocol): Likewise. * include/grub/parttool.h (grub_parttool_argdesc): Likewise. * include/grub/serial.h (grub_serial_find): Likewise. * include/grub/tparm.h (grub_terminfo_tparm): Likewise. * include/grub/xnu.h (grub_xnu_create_key): Likewise. (grub_xnu_create_value): Likewise. (grub_xnu_find_key): Likewise. (grub_xnu_scan_dir_for_kexts): Likewise. (grub_xnu_load_kext_from_dir): Likewise. * include/grub/zfs/zio_checksum.h (zio_checksum_t): Moved from here ... * grub-core/fs/zfs/zfs.c (zio_checksum_t): ...here. * include/grub/zfs/zio_checksum.h (zio_checksum_info): Moved from here ... * grub-core/fs/zfs/zfs.c (zio_checksum_info): ... here. Added missing const. --- ChangeLog | 63 ++++++++++++++++++++++++++++ grub-core/commands/i386/pc/sendkey.c | 4 +- grub-core/commands/lspci.c | 2 +- grub-core/commands/menuentry.c | 2 +- grub-core/disk/lvm.c | 4 +- grub-core/efiemu/i386/coredetect.c | 2 +- grub-core/efiemu/main.c | 2 +- grub-core/fs/hfsplus.c | 2 +- grub-core/fs/ntfs.c | 2 +- grub-core/fs/xfs.c | 4 +- grub-core/fs/zfs/zfs.c | 24 +++++++++-- grub-core/gnulib/regcomp.c | 2 +- grub-core/lib/legacy_parse.c | 2 +- grub-core/lib/posix_wrap/langinfo.h | 2 +- grub-core/loader/i386/bsd.c | 9 ++-- grub-core/loader/i386/xnu.c | 2 +- grub-core/loader/xnu.c | 23 +++++----- grub-core/normal/color.c | 2 +- grub-core/normal/completion.c | 2 +- grub-core/normal/menu_entry.c | 4 +- grub-core/term/serial.c | 4 +- grub-core/term/tparm.c | 2 +- include/grub/efiemu/efiemu.h | 2 +- include/grub/i386/bsd.h | 4 +- include/grub/lib/arg.h | 4 +- include/grub/net.h | 6 +-- include/grub/parttool.h | 4 +- include/grub/serial.h | 2 +- include/grub/tparm.h | 2 +- include/grub/xnu.h | 12 +++--- include/grub/zfs/zio_checksum.h | 16 ------- 31 files changed, 143 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07f3fb62c..0d0219d9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,66 @@ +2011-11-30 Vladimir Serbinenko + + Add missing const qualifiers. + + * grub-core/commands/i386/pc/sendkey.c (keysym): Add missing const. + * grub-core/commands/lspci.c (grub_pci_classname): Likewise. + * grub-core/commands/menuentry.c (hotkey_aliases): Likewise. + * grub-core/disk/lvm.c (grub_lvm_getvalue): Likewise. + (grub_lvm_check_flag): Likewise. + * grub-core/efiemu/i386/coredetect.c + (grub_efiemu_get_default_core_name): Likewise + * grub-core/efiemu/main.c (grub_efiemu_autocore): Likewise. + * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Likewise. + * grub-core/fs/ntfs.c (fixup): Likewise. + * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Likewise. + * grub-core/fs/zfs/zfs.c (decomp_entry): Likewise. + (fzap_lookup): Likewise. + (zap_lookup): Likewise. + * grub-core/gnulib/regcomp.c (init_dfa): Likewise. + * grub-core/lib/legacy_parse.c (check_option): Likewise. + * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Likewise. + * grub-core/loader/i386/bsd.c (grub_bsd_add_meta): Likewise. + (grub_freebsd_add_meta_module): Likewise. + (grub_cmd_freebsd_module): Likewise. + * grub-core/loader/i386/xnu.c (tbl_alias): Likewise. + * grub-core/loader/xnu.c (grub_xnu_register_memory): Likewise. + (grub_xnu_writetree_get_size): Likewise. + (grub_xnu_writetree_toheap_real): Likewise. + (grub_xnu_find_key): Likewise. + (grub_xnu_create_key): Likewise. + (grub_xnu_create_value): Likewise. + (grub_xnu_register_memory): Likewise. + (grub_xnu_check_os_bundle_required): Likewise. + (grub_xnu_scan_dir_for_kexts): Likewise. + (grub_xnu_load_kext_from_dir): Likewise. + * grub-core/normal/color.c (color_list): Likewise. + * grub-core/normal/completion.c (current_word): Likewise. + * grub-core/normal/menu_entry.c (insert_string): Likewise. + * grub-core/term/serial.c (grub_serial_find): Likewise. + * grub-core/term/tparm.c (grub_terminfo_tparm): Likewise. + * include/grub/efiemu/efiemu.h (grub_efiemu_get_default_core_name): + Likewise. + * include/grub/i386/bsd.h (grub_bsd_add_meta): Likewise. + (grub_freebsd_add_meta_module): Likewise. + * include/grub/lib/arg.h (grub_arg_option): Likewise. + * include/grub/net.h (grub_net_card_driver): Likewise. + (grub_net_card): Likewise. + (grub_net_app_protocol): Likewise. + * include/grub/parttool.h (grub_parttool_argdesc): Likewise. + * include/grub/serial.h (grub_serial_find): Likewise. + * include/grub/tparm.h (grub_terminfo_tparm): Likewise. + * include/grub/xnu.h (grub_xnu_create_key): Likewise. + (grub_xnu_create_value): Likewise. + (grub_xnu_find_key): Likewise. + (grub_xnu_scan_dir_for_kexts): Likewise. + (grub_xnu_load_kext_from_dir): Likewise. + + * include/grub/zfs/zio_checksum.h (zio_checksum_t): Moved from here ... + * grub-core/fs/zfs/zfs.c (zio_checksum_t): ...here. + * include/grub/zfs/zio_checksum.h (zio_checksum_info): + Moved from here ... + * grub-core/fs/zfs/zfs.c (zio_checksum_info): ... here. Added missing const. + 2011-11-28 Colin Watson * util/getroot.c (find_root_device_from_libzfs): Use xasprintf. diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index 83400c347..80094c795 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -63,8 +63,8 @@ static grub_uint32_t andmask = 0xffffffff, ormask = 0; struct keysym { - char *unshifted_name; /* the name in unshifted state */ - char *shifted_name; /* the name in shifted state */ + const char *unshifted_name; /* the name in unshifted state */ + const char *shifted_name; /* the name in shifted state */ unsigned char unshifted_ascii; /* the ascii code in unshifted state */ unsigned char shifted_ascii; /* the ascii code in shifted state */ unsigned char keycode; /* keyboard scancode */ diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c index 03541df6c..9f836298f 100644 --- a/grub-core/commands/lspci.c +++ b/grub-core/commands/lspci.c @@ -29,7 +29,7 @@ struct grub_pci_classname { int class; int subclass; - char *desc; + const char *desc; }; static const struct grub_pci_classname grub_pci_classes[] = diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index f5ec60bff..57e4baa61 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -40,7 +40,7 @@ static const struct grub_arg_option options[] = static struct { - char *name; + const char *name; int key; } hotkey_aliases[] = { diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 2fd736439..f3a99c66e 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -44,7 +44,7 @@ static int is_lv_readable (struct grub_lvm_lv *lv); at the number. In case STR is not found, *P will be NULL and the return value will be 0. */ static int -grub_lvm_getvalue (char **p, char *str) +grub_lvm_getvalue (char **p, const char *str) { *p = grub_strstr (*p, str); if (! *p) @@ -69,7 +69,7 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl) #endif static int -grub_lvm_check_flag (char *p, char *str, char *flag) +grub_lvm_check_flag (char *p, const char *str, const char *flag) { int len_str = grub_strlen (str), len_flag = grub_strlen (flag); while (1) diff --git a/grub-core/efiemu/i386/coredetect.c b/grub-core/efiemu/i386/coredetect.c index 975c4aa5d..c3782fda9 100644 --- a/grub-core/efiemu/i386/coredetect.c +++ b/grub-core/efiemu/i386/coredetect.c @@ -26,7 +26,7 @@ #define bit_LM (1 << 29) -char * +const char * grub_efiemu_get_default_core_name (void) { diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index 126ecf9e7..f2c038110 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -227,7 +227,7 @@ grub_efiemu_autocore (void) { const char *prefix; char *filename; - char *suffix; + const char *suffix; grub_err_t err; if (grub_efiemu_sizeof_uintn_t () != 0) diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 3d9bc42fa..00b2366bf 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -181,7 +181,7 @@ enum grub_hfsplus_filetype struct grub_hfsplus_catkey_internal { grub_uint32_t parent; - char *name; + const char *name; }; /* Internal representation of an extent overflow key. */ diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index ac695a29f..a432adce3 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -47,7 +47,7 @@ static grub_dl_t my_mod; grub_ntfscomp_func_t grub_ntfscomp_func; static grub_err_t -fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) +fixup (struct grub_ntfs_data *data, char *buf, int len, const char *magic) { int ss; char *pu; diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index c4d47a099..c7ce3aac9 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -451,9 +451,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_node_t node)) { struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; - auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename); + auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename); - int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename) + int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename) { struct grub_fshelp_node *fdiro; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index be659f52c..9de2ab586 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -131,10 +131,26 @@ typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len); typedef struct decomp_entry { - char *name; + const char *name; zfs_decomp_func_t *decomp_func; } decomp_entry_t; +/* + * Signature for checksum functions. + */ +typedef void zio_checksum_t(const void *data, grub_uint64_t size, + grub_zfs_endian_t endian, zio_cksum_t *zcp); + +/* + * Information about each checksum function. + */ +typedef struct zio_checksum_info { + zio_checksum_t *ci_func; /* checksum function for each byteorder */ + int ci_correctable; /* number of correctable bits */ + int ci_eck; /* uses zio embedded checksum? */ + const char *ci_name; /* descriptive name */ +} zio_checksum_info_t; + typedef struct dnode_end { dnode_phys_t dn; @@ -1933,8 +1949,8 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) /* XXX */ static grub_err_t fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, - char *name, grub_uint64_t * value, struct grub_zfs_data *data, - int case_insensitive) + const char *name, grub_uint64_t * value, + struct grub_zfs_data *data, int case_insensitive) { void *l; grub_uint64_t hash, idx, blkid; @@ -2096,7 +2112,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, * */ static grub_err_t -zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, +zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, struct grub_zfs_data *data, int case_insensitive) { grub_uint64_t block_type; diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c index 86ca02b0c..23f3afa01 100644 --- a/grub-core/gnulib/regcomp.c +++ b/grub-core/gnulib/regcomp.c @@ -851,7 +851,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) { __re_size_t table_size; #ifndef _LIBC - char *codeset_name; + const char *codeset_name; #endif #ifdef RE_ENABLE_I18N size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 43fca51dc..e429f2f1b 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -402,7 +402,7 @@ adjust_file (const char *in, grub_size_t len) } static int -check_option (const char *a, char *b, grub_size_t len) +check_option (const char *a, const char *b, grub_size_t len) { if (grub_strlen (b) != len) return 0; diff --git a/grub-core/lib/posix_wrap/langinfo.h b/grub-core/lib/posix_wrap/langinfo.h index 72b5b9612..ab75af15d 100644 --- a/grub-core/lib/posix_wrap/langinfo.h +++ b/grub-core/lib/posix_wrap/langinfo.h @@ -23,7 +23,7 @@ typedef enum { CODESET } nl_item; -static inline char * +static inline const char * nl_langinfo (nl_item item) { switch (item) diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 6746b3853..f9bab21e6 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -206,7 +206,7 @@ grub_bsd_get_device (grub_uint32_t * biosdev, } grub_err_t -grub_bsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len) +grub_bsd_add_meta (grub_uint32_t type, const void *data, grub_uint32_t len) { struct bsd_tag *newtag; @@ -383,10 +383,11 @@ grub_bsd_add_mmap (void) } grub_err_t -grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv, +grub_freebsd_add_meta_module (const char *filename, const char *type, + int argc, char **argv, grub_addr_t addr, grub_uint32_t size) { - char *name; + const char *name; name = grub_strrchr (filename, '/'); if (name) name++; @@ -1806,7 +1807,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; int modargc; char **modargv; - char *type; + const char *type; grub_err_t err; void *src; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 36893ae62..1df8dc4c0 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -46,7 +46,7 @@ grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack; struct tbl_alias { grub_efi_guid_t guid; - char *name; + const char *name; }; static struct tbl_alias table_aliases[] = diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index a98d60c20..f96bc2b75 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -50,7 +50,7 @@ grub_size_t grub_xnu_heap_size = 0; struct grub_relocator *grub_xnu_relocator; static grub_err_t -grub_xnu_register_memory (char *prefix, int *suffix, +grub_xnu_register_memory (const char *prefix, int *suffix, grub_addr_t addr, grub_size_t size); grub_err_t grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target) @@ -103,7 +103,8 @@ grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur) /* Compute the size of device tree in xnu format. */ static grub_size_t -grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name) +grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, + const char *name) { grub_size_t ret; struct grub_xnu_devtree_key *cur; @@ -134,7 +135,8 @@ grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name) /* Write devtree in XNU format at curptr assuming the head is named NAME.*/ static void * grub_xnu_writetree_toheap_real (void *curptr, - struct grub_xnu_devtree_key *start, char *name) + struct grub_xnu_devtree_key *start, + const char *name) { struct grub_xnu_devtree_key *cur; int nkeys = 0, nvals = 0; @@ -249,7 +251,7 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) /* Find a key or value in parent key. */ struct grub_xnu_devtree_key * -grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name) +grub_xnu_find_key (struct grub_xnu_devtree_key *parent, const char *name) { struct grub_xnu_devtree_key *cur; for (cur = parent; cur; cur = cur->next) @@ -259,7 +261,7 @@ grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name) } struct grub_xnu_devtree_key * -grub_xnu_create_key (struct grub_xnu_devtree_key **parent, char *name) +grub_xnu_create_key (struct grub_xnu_devtree_key **parent, const char *name) { struct grub_xnu_devtree_key *ret; ret = grub_xnu_find_key (*parent, name); @@ -285,7 +287,7 @@ grub_xnu_create_key (struct grub_xnu_devtree_key **parent, char *name) } struct grub_xnu_devtree_key * -grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name) +grub_xnu_create_value (struct grub_xnu_devtree_key **parent, const char *name) { struct grub_xnu_devtree_key *ret; ret = grub_xnu_find_key (*parent, name); @@ -562,7 +564,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), /* Register a memory in a memory map under name PREFIXSUFFIX and increment SUFFIX. */ static grub_err_t -grub_xnu_register_memory (char *prefix, int *suffix, +grub_xnu_register_memory (const char *prefix, int *suffix, grub_addr_t addr, grub_size_t size) { struct grub_xnu_devtree_key *chosen; @@ -918,7 +920,8 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), /* Returns true if the kext should be loaded according to plist and osbundlereq. Also fill BINNAME. */ static int -grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq, +grub_xnu_check_os_bundle_required (char *plistname, + const char *osbundlereq, char **binname) { grub_file_t file; @@ -1033,7 +1036,7 @@ grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq, /* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */ grub_err_t -grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, +grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired, int maxrecursion) { grub_device_t dev; @@ -1099,7 +1102,7 @@ grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, /* Load extension DIRNAME. (extensions are directories in xnu) */ grub_err_t -grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, +grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, int maxrecursion) { grub_device_t dev; diff --git a/grub-core/normal/color.c b/grub-core/normal/color.c index 2e6c80b94..06f1a877c 100644 --- a/grub-core/normal/color.c +++ b/grub-core/normal/color.c @@ -23,7 +23,7 @@ #include /* Borrowed from GRUB Legacy */ -static char *color_list[16] = +static const char *color_list[16] = { "black", "blue", diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index 67676dfe4..8568cd892 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -28,7 +28,7 @@ #include /* The current word. */ -static char *current_word; +static const char *current_word; /* The matched string. */ static char *match; diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index dc5ab528f..7af093fd8 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -317,7 +317,7 @@ update_screen_all (struct screen *screen, } static int -insert_string (struct screen *screen, char *s, int update) +insert_string (struct screen *screen, const char *s, int update) { int region_start = screen->num_lines; int region_column = 0; @@ -397,7 +397,7 @@ insert_string (struct screen *screen, char *s, int update) else { /* All but LF. */ - char *p; + const char *p; struct line *current_linep; int size; int orig_num[screen->nterms], new_num[screen->nterms]; diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 86935626c..7b970587f 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -126,7 +126,7 @@ static struct grub_term_output grub_serial_term_output = struct grub_serial_port * -grub_serial_find (char *name) +grub_serial_find (const char *name) { struct grub_serial_port *port; @@ -157,7 +157,7 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; char pname[40]; - char *name = NULL; + const char *name = NULL; struct grub_serial_port *port; struct grub_serial_config config; grub_err_t err; diff --git a/grub-core/term/tparm.c b/grub-core/term/tparm.c index 076a192a5..8c1c288a0 100644 --- a/grub-core/term/tparm.c +++ b/grub-core/term/tparm.c @@ -745,7 +745,7 @@ tparam_internal(const char *string, va_list ap) return (out_buff); } -char * +const char * grub_terminfo_tparm (const char *string, ...) { va_list ap; diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 9cedc3226..7b9551627 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -272,7 +272,7 @@ grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value, grub_err_t grub_efiemu_write_sym_markers (void); grub_err_t grub_efiemu_pnvram (void); grub_err_t grub_efiemu_prepare (void); -char *grub_efiemu_get_default_core_name (void); +const char *grub_efiemu_get_default_core_name (void); void grub_efiemu_pnvram_cmd_unregister (void); grub_err_t grub_efiemu_autocore (void); grub_err_t grub_efiemu_crc32 (void); diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 53008cdaf..c9e8b7dd2 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -94,8 +94,8 @@ grub_err_t grub_netbsd_load_elf_meta64 (struct grub_relocator *relocator, grub_addr_t *kern_end); grub_err_t grub_bsd_add_meta (grub_uint32_t type, - void *data, grub_uint32_t len); -grub_err_t grub_freebsd_add_meta_module (char *filename, char *type, + const void *data, grub_uint32_t len); +grub_err_t grub_freebsd_add_meta_module (const char *filename, const char *type, int argc, char **argv, grub_addr_t addr, grub_uint32_t size); diff --git a/include/grub/lib/arg.h b/include/grub/lib/arg.h index b61f6f30e..f81af85ee 100644 --- a/include/grub/lib/arg.h +++ b/include/grub/lib/arg.h @@ -53,8 +53,8 @@ struct grub_arg_option const char *longarg; int shortarg; int flags; - char *doc; - char *arg; + const char *doc; + const char *arg; grub_arg_type_t type; }; diff --git a/include/grub/net.h b/include/grub/net.h index 45d08f3f5..03af637b5 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -59,7 +59,7 @@ struct grub_net_card; struct grub_net_card_driver { struct grub_net_card_driver *next; - char *name; + const char *name; grub_err_t (*open) (const struct grub_net_card *dev); void (*close) (const struct grub_net_card *dev); grub_err_t (*send) (const struct grub_net_card *dev, @@ -89,7 +89,7 @@ typedef struct grub_net_packets struct grub_net_card { struct grub_net_card *next; - char *name; + const char *name; struct grub_net_card_driver *driver; grub_net_link_level_address_t default_address; grub_net_card_flags_t flags; @@ -188,7 +188,7 @@ typedef struct grub_net_socket *grub_net_socket_t; struct grub_net_app_protocol { struct grub_net_app_protocol *next; - char *name; + const char *name; grub_err_t (*dir) (grub_device_t device, const char *path, int (*hook) (const char *filename, const struct grub_dirhook_info *info)); diff --git a/include/grub/parttool.h b/include/grub/parttool.h index 8291e1161..4e8f8d5e5 100644 --- a/include/grub/parttool.h +++ b/include/grub/parttool.h @@ -21,8 +21,8 @@ struct grub_parttool_argdesc { - char *name; - char *desc; + const char *name; + const char *desc; enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL} type; }; diff --git a/include/grub/serial.h b/include/grub/serial.h index 49ac0623a..feaa5b1a7 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -143,7 +143,7 @@ grub_serial_config_defaults (struct grub_serial_port *port) void grub_ns8250_init (void); char *grub_serial_ns8250_add_port (grub_port_t port); -struct grub_serial_port *grub_serial_find (char *name); +struct grub_serial_port *grub_serial_find (const char *name); extern struct grub_serial_driver grub_ns8250_driver; void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); diff --git a/include/grub/tparm.h b/include/grub/tparm.h index 642a22f90..0c6f9e0f0 100644 --- a/include/grub/tparm.h +++ b/include/grub/tparm.h @@ -21,6 +21,6 @@ #define GRUB_TPARM_HEADER 1 /* Function prototypes. */ -char *grub_terminfo_tparm (const char *string, ...); +const char *grub_terminfo_tparm (const char *string, ...); #endif /* ! GRUB_TPARM_HEADER */ diff --git a/include/grub/xnu.h b/include/grub/xnu.h index 076aeb5ed..2a096d803 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -81,7 +81,7 @@ struct grub_xnu_extheader } __attribute__ ((packed)); struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent, - char *name); + const char *name); extern struct grub_xnu_devtree_key *grub_xnu_devtree_root; @@ -89,18 +89,20 @@ void grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur); grub_err_t grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size); struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key **parent, - char *name); + const char *name); void grub_xnu_lock (void); void grub_xnu_unlock (void); grub_err_t grub_xnu_resume (char *imagename); grub_err_t grub_xnu_boot_resume (void); struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent, - char *name); + const char *name); grub_err_t grub_xnu_align_heap (int align); -grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired, +grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, + const char *osbundlerequired, int maxrecursion); -grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, +grub_err_t grub_xnu_load_kext_from_dir (char *dirname, + const char *osbundlerequired, int maxrecursion); grub_err_t grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target); grub_err_t grub_xnu_fill_devicetree (void); diff --git a/include/grub/zfs/zio_checksum.h b/include/grub/zfs/zio_checksum.h index 0ef5a3ec7..e03c85a83 100644 --- a/include/grub/zfs/zio_checksum.h +++ b/include/grub/zfs/zio_checksum.h @@ -23,22 +23,6 @@ #ifndef _SYS_ZIO_CHECKSUM_H #define _SYS_ZIO_CHECKSUM_H -/* - * Signature for checksum functions. - */ -typedef void zio_checksum_t(const void *data, grub_uint64_t size, - grub_zfs_endian_t endian, zio_cksum_t *zcp); - -/* - * Information about each checksum function. - */ -typedef struct zio_checksum_info { - zio_checksum_t *ci_func; /* checksum function for each byteorder */ - int ci_correctable; /* number of correctable bits */ - int ci_eck; /* uses zio embedded checksum? */ - char *ci_name; /* descriptive name */ -} zio_checksum_info_t; - extern void zio_checksum_SHA256 (const void *, grub_uint64_t, grub_zfs_endian_t endian, zio_cksum_t *); extern void fletcher_2 (const void *, grub_uint64_t, grub_zfs_endian_t endian, From 48d6e4565339147c635a4ab47e76a82fb2f40283 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 12 Dec 2011 22:20:14 +0100 Subject: [PATCH 242/315] * grub-core/disk/ahci.c (grub_ahci_pciinit): Fix compat condition. --- ChangeLog | 4 ++++ grub-core/disk/ahci.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0d0219d9e..492c45b72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-12 Vladimir Serbinenko + + * grub-core/disk/ahci.c (grub_ahci_pciinit): Fix compat condition. + 2011-11-30 Vladimir Serbinenko Add missing const qualifiers. diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 38c4d5e2d..00fc889a7 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -305,7 +305,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, else grub_dprintf ("ahci", "AHCI is already in OS mode\n"); - if (~(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN)) + if (!(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN)) grub_dprintf ("ahci", "AHCI is in compat mode. Switching\n"); else grub_dprintf ("ahci", "AHCI is in AHCI mode.\n"); From 1bc8f60db7e7da5ea77d4bf21b82a3731a5c462f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 12 Dec 2011 22:40:43 +0100 Subject: [PATCH 243/315] * include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const. * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to UTF-16-BE. All users updated. (grub_hfsplus_cmp_catkey): Fix unicode handling. (grub_hfsplus_iterate_dir): Likewise. (grub_hfsplus_label): Likewise. --- ChangeLog | 9 ++++ grub-core/fs/hfsplus.c | 93 +++++++++++++++--------------------------- include/grub/charset.h | 2 + 3 files changed, 43 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 492c45b72..485d37f30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-12-12 Vladimir Serbinenko + + * include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const. + * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to + UTF-16-BE. All users updated. + (grub_hfsplus_cmp_catkey): Fix unicode handling. + (grub_hfsplus_iterate_dir): Likewise. + (grub_hfsplus_label): Likewise. + 2011-12-12 Vladimir Serbinenko * grub-core/disk/ahci.c (grub_ahci_pciinit): Fix compat condition. diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 00b2366bf..9d5f20181 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -181,7 +181,8 @@ enum grub_hfsplus_filetype struct grub_hfsplus_catkey_internal { grub_uint32_t parent; - const char *name; + const grub_uint16_t *name; + grub_size_t namelen; }; /* Internal representation of an extent overflow key. */ @@ -519,8 +520,6 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, { struct grub_hfsplus_catkey *catkey_a = &keya->catkey; struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; - char *filename; - int i; int diff; /* Safe unsigned comparison */ @@ -530,26 +529,13 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, if (aparent < catkey_b->parent) return -1; - /* Change the filename in keya so the endianness is correct. */ - for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) - catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]); + diff = grub_memcmp (catkey_a->name, catkey_b->name, + grub_min (grub_be_to_cpu16 (catkey_a->namelen), + catkey_b->namelen) + * sizeof (catkey_a->name[0])); + if (diff == 0) + diff = grub_be_to_cpu16 (catkey_a->namelen) - catkey_b->namelen; - filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1); - - if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name, - grub_be_to_cpu16 (catkey_a->namelen))) - return -1; /* XXX: This error never occurs, but in case it happens - just skip this entry. */ - - diff = grub_strncmp (filename, catkey_b->name, - grub_be_to_cpu16 (catkey_a->namelen)); - - grub_free (filename); - - /* The endianness was changed to host format, change it back to - whatever it was. */ - for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) - catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]); return diff; } @@ -792,6 +778,11 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, if (type == GRUB_FSHELP_UNKNOWN) return 0; + filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! filename) + return 0; + /* Make sure the byte order of the UTF16 string is correct. */ for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) { @@ -802,18 +793,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, return 0; } - filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1); - if (! filename) - return 0; - - if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, - grub_be_to_cpu16 (catkey->namelen))) - { - grub_free (filename); - return 0; - } - - filename[grub_be_to_cpu16 (catkey->namelen)] = '\0'; + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, + grub_be_to_cpu16 (catkey->namelen)) = '\0'; /* Restore the byte order to what it was previously. */ for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) @@ -823,22 +804,18 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, if (! dir->data->case_sensitive) type |= GRUB_FSHELP_CASE_INSENSITIVE; - /* Only accept valid nodes. */ - if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen)) - { - /* A valid node is found; setup the node and call the - callback function. */ - node = grub_malloc (sizeof (*node)); - node->data = dir->data; + /* A valid node is found; setup the node and call the + callback function. */ + node = grub_malloc (sizeof (*node)); + node->data = dir->data; - grub_memcpy (node->extents, fileinfo->data.extents, - sizeof (node->extents)); - node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; - node->size = grub_be_to_cpu64 (fileinfo->data.size); - node->fileid = grub_be_to_cpu32 (fileinfo->fileid); + grub_memcpy (node->extents, fileinfo->data.extents, + sizeof (node->extents)); + node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; + node->size = grub_be_to_cpu64 (fileinfo->data.size); + node->fileid = grub_be_to_cpu32 (fileinfo->fileid); - ret = hook (filename, type, node); - } + ret = hook (filename, type, node); grub_free (filename); @@ -851,7 +828,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, /* Create a key that points to the first entry in the directory. */ intern.catkey.parent = dir->fileid; - intern.catkey.name = ""; + intern.catkey.name = 0; + intern.catkey.namelen = 0; /* First lookup the first entry. */ if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern, @@ -999,7 +977,8 @@ grub_hfsplus_label (grub_device_t device, char **label) /* Create a key that points to the label. */ intern.catkey.parent = 1; - intern.catkey.name = ""; + intern.catkey.name = 0; + intern.catkey.namelen = 0; /* First lookup the first entry. */ if (grub_hfsplus_btree_search (&data->catalog_tree, &intern, @@ -1022,20 +1001,12 @@ grub_hfsplus_label (grub_device_t device, char **label) return 0; } - *label = grub_malloc (label_len + 1); + *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); if (! *label) return grub_errno; - if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, - label_len)) - { - grub_free (node); - grub_free (*label); - grub_free (data); - *label = 0; - return grub_errno; - } - (*label)[label_len] = '\0'; + *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, + label_len) = '\0'; grub_free (node); grub_free (data); diff --git a/include/grub/charset.h b/include/grub/charset.h index c8247f78a..13443dad2 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -36,6 +36,8 @@ #define GRUB_UINT8_5_TRAILINGBITS 0x1f #define GRUB_UINT8_6_TRAILINGBITS 0x3f +#define GRUB_MAX_UTF8_PER_UTF16 4 + #define GRUB_UCS2_LIMIT 0x10000 #define GRUB_UTF16_UPPER_SURROGATE(code) \ (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff)) From 74dbd24466ce74d6925a804d9a2c77227583ba7a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 00:28:14 +0100 Subject: [PATCH 244/315] * include/grub/loader.h (grub_loader_register_preboot_hook): Use struct preboot * and not void * for handle. All users updated. (grub_loader_unregister_preboot_hook): Likewise. --- ChangeLog | 6 ++++++ grub-core/bus/usb/ohci.c | 2 +- grub-core/commands/boot.c | 22 +++++++++++----------- grub-core/commands/i386/pc/sendkey.c | 2 +- grub-core/disk/ahci.c | 2 +- grub-core/mmap/i386/pc/mmap.c | 2 +- grub-core/net/net.c | 2 +- include/grub/loader.h | 10 ++++++---- 8 files changed, 28 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 485d37f30..ec65fb11e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/loader.h (grub_loader_register_preboot_hook): + Use struct preboot * and not void * for handle. All users updated. + (grub_loader_unregister_preboot_hook): Likewise. + 2011-12-12 Vladimir Serbinenko * include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const. diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index b659c3f62..2291619cb 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -1426,7 +1426,7 @@ static struct grub_usb_controller_dev usb_controller = .detect_dev = grub_ohci_detect_dev }; -static void *fini_hnd; +static struct grub_preboot *fini_hnd; GRUB_MOD_INIT(ohci) { diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c index 7714011bf..5149074c7 100644 --- a/grub-core/commands/boot.c +++ b/grub-core/commands/boot.c @@ -31,17 +31,17 @@ static grub_err_t (*grub_loader_boot_func) (void); static grub_err_t (*grub_loader_unload_func) (void); static int grub_loader_noreturn; -struct grub_preboot_t +struct grub_preboot { grub_err_t (*preboot_func) (int); grub_err_t (*preboot_rest_func) (void); grub_loader_preboot_hook_prio_t prio; - struct grub_preboot_t *next; - struct grub_preboot_t *prev; + struct grub_preboot *next; + struct grub_preboot *prev; }; static int grub_loader_loaded; -static struct grub_preboot_t *preboots_head = 0, +static struct grub_preboot *preboots_head = 0, *preboots_tail = 0; int @@ -51,18 +51,18 @@ grub_loader_is_loaded (void) } /* Register a preboot hook. */ -void * +struct grub_preboot * grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn), grub_err_t (*preboot_rest_func) (void), grub_loader_preboot_hook_prio_t prio) { - struct grub_preboot_t *cur, *new_preboot; + struct grub_preboot *cur, *new_preboot; if (! preboot_func && ! preboot_rest_func) return 0; - new_preboot = (struct grub_preboot_t *) - grub_malloc (sizeof (struct grub_preboot_t)); + new_preboot = (struct grub_preboot *) + grub_malloc (sizeof (struct grub_preboot)); if (! new_preboot) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added"); @@ -96,9 +96,9 @@ grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn), } void -grub_loader_unregister_preboot_hook (void *hnd) +grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) { - struct grub_preboot_t *preb = hnd; + struct grub_preboot *preb = hnd; if (preb->next) preb->next->prev = preb->prev; @@ -143,7 +143,7 @@ grub_err_t grub_loader_boot (void) { grub_err_t err = GRUB_ERR_NONE; - struct grub_preboot_t *cur; + struct grub_preboot *cur; if (! grub_loader_loaded) return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel"); diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index 80094c795..ab1090672 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -365,7 +365,7 @@ grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) } static grub_extcmd_t cmd; -static void *preboot_hook; +static struct grub_preboot *preboot_hook; GRUB_MOD_INIT (sendkey) { diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 00fc889a7..10b7be687 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -706,7 +706,7 @@ static struct grub_ata_dev grub_ahci_dev = -static void *fini_hnd; +static struct grub_preboot *fini_hnd; GRUB_MOD_INIT(ahci) { diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c index 8dec083f8..baa41aa2d 100644 --- a/grub-core/mmap/i386/pc/mmap.c +++ b/grub-core/mmap/i386/pc/mmap.c @@ -191,7 +191,7 @@ grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), int handle __attribute__ ((unused))) { grub_err_t err; - static void *preb_handle = 0; + static struct grub_preboot *preb_handle = 0; err = malloc_hook (); if (err) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 09acea900..d4e445e71 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -937,7 +937,7 @@ grub_net_restore_hw (void) return GRUB_ERR_NONE; } -static void *fini_hnd; +static struct grub_preboot *fini_hnd; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_lsroutes, cmd_lscards; diff --git a/include/grub/loader.h b/include/grub/loader.h index f38deb96a..1d70ef049 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -56,11 +56,13 @@ typedef enum { } grub_loader_preboot_hook_prio_t; /* Register a preboot hook. */ -void *EXPORT_FUNC(grub_loader_register_preboot_hook) (grub_err_t (*preboot_func) (int noret), - grub_err_t (*preboot_rest_func) (void), - grub_loader_preboot_hook_prio_t prio); +struct grub_preboot; + +struct grub_preboot *EXPORT_FUNC(grub_loader_register_preboot_hook) (grub_err_t (*preboot_func) (int noret), + grub_err_t (*preboot_rest_func) (void), + grub_loader_preboot_hook_prio_t prio); /* Unregister given preboot hook. */ -void EXPORT_FUNC (grub_loader_unregister_preboot_hook) (void *hnd); +void EXPORT_FUNC (grub_loader_unregister_preboot_hook) (struct grub_preboot *hnd); #endif /* ! GRUB_LOADER_HEADER */ From 0af2346fdb41b8663ccdfa887e1c699209ca792d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 00:29:42 +0100 Subject: [PATCH 245/315] * grub-core/bus/usb/ohci.c (grub_ohci_check_transfer): Add an unsigned specification. --- ChangeLog | 5 +++++ grub-core/bus/usb/ohci.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec65fb11e..43b5d59d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/bus/usb/ohci.c (grub_ohci_check_transfer): Add an unsigned + specification. + 2011-12-13 Vladimir Serbinenko * include/grub/loader.h (grub_loader_register_preboot_hook): diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 2291619cb..3f5ca7b03 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -1152,8 +1152,8 @@ grub_ohci_check_transfer (grub_usb_controller_t dev, return parse_halt (dev, transfer, actual); /* Finished ED detection */ - if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) == - (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */ + if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xfU) == + (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xfU) ) /* Empty ED */ { /* Check the HALT bit */ /* It looks like nonsense - it was tested previously... From c5fc563aff65bd7c9211841cbe5cd23b70084a6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 00:50:49 +0100 Subject: [PATCH 246/315] Enable UTF8 in gnulib regexp. * config.h.in (RE_ENABLE_I18N) [!GRUB_UTIL]: New define. * grub-core/lib/posix_wrap/ctype.h (islower): Use grub_islower. (isupper): Use grub_isupper. (isascii): New inline function. * grub-core/lib/posix_wrap/wchar.h: Replace dummy with real contents. * grub-core/lib/posix_wrap/wctype.h: Likewise. * grub-core/normal/charset.c (grub_utf8_process): New function. (grub_utf8_to_utf16): Use grub_utf8_process. (grub_encode_utf8_character): New function. (grub_ucs4_to_utf8): Use grub_encode_utf8_character. * include/grub/charset.h (grub_utf8_process): New declaration. (grub_encode_utf8_character): Likewise. * include/grub/misc.h (grub_islower): New inline function. (grub_isupper): Likewise. (grub_strchrsub): Moved down to fix the definitions. --- ChangeLog | 20 +++ config.h.in | 2 + grub-core/lib/posix_wrap/ctype.h | 10 +- grub-core/lib/posix_wrap/wchar.h | 87 ++++++++++++- grub-core/lib/posix_wrap/wctype.h | 106 ++++++++++++++++ grub-core/normal/charset.c | 197 +++++++++++++++++------------- include/grub/charset.h | 11 ++ include/grub/misc.h | 53 ++++---- 8 files changed, 380 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43b5d59d3..91eca49ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-12-13 Vladimir Serbinenko + + Enable UTF8 in gnulib regexp. + + * config.h.in (RE_ENABLE_I18N) [!GRUB_UTIL]: New define. + * grub-core/lib/posix_wrap/ctype.h (islower): Use grub_islower. + (isupper): Use grub_isupper. + (isascii): New inline function. + * grub-core/lib/posix_wrap/wchar.h: Replace dummy with real contents. + * grub-core/lib/posix_wrap/wctype.h: Likewise. + * grub-core/normal/charset.c (grub_utf8_process): New function. + (grub_utf8_to_utf16): Use grub_utf8_process. + (grub_encode_utf8_character): New function. + (grub_ucs4_to_utf8): Use grub_encode_utf8_character. + * include/grub/charset.h (grub_utf8_process): New declaration. + (grub_encode_utf8_character): Likewise. + * include/grub/misc.h (grub_islower): New inline function. + (grub_isupper): Likewise. + (grub_strchrsub): Moved down to fix the definitions. + 2011-12-13 Vladimir Serbinenko * grub-core/bus/usb/ohci.c (grub_ohci_check_transfer): Add an unsigned diff --git a/config.h.in b/config.h.in index 92d7a07f2..39b8fbafd 100644 --- a/config.h.in +++ b/config.h.in @@ -39,6 +39,8 @@ /* Define to 1 to enable disk cache statistics. */ #define DISK_CACHE_STATS @DISK_CACHE_STATS@ +#define RE_ENABLE_I18N 1 + #if defined(__i386__) #define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) #else diff --git a/grub-core/lib/posix_wrap/ctype.h b/grub-core/lib/posix_wrap/ctype.h index 9589778b6..38b572703 100644 --- a/grub-core/lib/posix_wrap/ctype.h +++ b/grub-core/lib/posix_wrap/ctype.h @@ -42,13 +42,19 @@ isdigit (int c) static inline int islower (int c) { - return (c >= 'a' && c <= 'z'); + return grub_islower (c); +} + +static inline int +isascii (int c) +{ + return !(c & ~0x7f); } static inline int isupper (int c) { - return (c >= 'A' && c <= 'Z'); + return grub_isupper (c); } static inline int diff --git a/grub-core/lib/posix_wrap/wchar.h b/grub-core/lib/posix_wrap/wchar.h index fd56fd332..a696643de 100644 --- a/grub-core/lib/posix_wrap/wchar.h +++ b/grub-core/lib/posix_wrap/wchar.h @@ -19,7 +19,92 @@ #ifndef GRUB_POSIX_WCHAR_H #define GRUB_POSIX_WCHAR_H 1 +#include + /* UCS-4. */ -typedef grub_uint32_t wchar_t; +typedef grub_int32_t wint_t; +enum + { + WEOF = -1 + }; + +#define MB_LEN_MAX 4 + +/* UCS-4. */ +typedef grub_int32_t wchar_t; + +typedef struct mbstate { + grub_uint32_t code; + int count; +} mbstate_t; + +static inline size_t +mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ + const char *ptr; + if (!s) + { + pwc = 0; + s = ""; + n = 1; + } + + for (ptr = s; ptr < s + n; ptr++) + { + if (!grub_utf8_process (*ptr, &ps->code, &ps->count)) + return -1; + if (ps->count) + continue; + if (pwc) + *pwc = ps->code; + if (ps->code == 0) + return 0; + return ptr - s + 1; + } + return -2; +} + +static inline int +mbsinit(const mbstate_t *ps) +{ + return ps->count == 0; +} + +static inline size_t +wcrtomb (char *s, wchar_t wc, mbstate_t *ps __attribute__ ((unused))) +{ + if (s == 0) + return 1; + return grub_encode_utf8_character ((grub_uint8_t *) s, + (grub_uint8_t *) s + MB_LEN_MAX, + wc); +} + +static inline wint_t btowc (int c) +{ + if (c & ~0x7f) + return WEOF; + return c; +} + + +static inline int +wcscoll (const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 && *s2) + { + if (*s1 != *s2) + break; + + s1++; + s2++; + } + + if (*s1 < *s2) + return -1; + if (*s1 > *s2) + return +1; + return 0; +} #endif diff --git a/grub-core/lib/posix_wrap/wctype.h b/grub-core/lib/posix_wrap/wctype.h index e69de29bb..b2b33ab08 100644 --- a/grub-core/lib/posix_wrap/wctype.h +++ b/grub-core/lib/posix_wrap/wctype.h @@ -0,0 +1,106 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010, 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 . + */ + +#ifndef GRUB_POSIX_WCTYPE_H +#define GRUB_POSIX_WCTYPE_H 1 + +#include +#include + +typedef enum { GRUB_CTYPE_INVALID, + GRUB_CTYPE_ALNUM, GRUB_CTYPE_CNTRL, GRUB_CTYPE_LOWER, + GRUB_CTYPE_SPACE, GRUB_CTYPE_ALPHA, GRUB_CTYPE_DIGIT, + GRUB_CTYPE_PRINT, GRUB_CTYPE_UPPER, GRUB_CTYPE_BLANK, + GRUB_CTYPE_GRAPH, GRUB_CTYPE_PUNCT, GRUB_CTYPE_XDIGIT, + GRUB_CTYPE_MAX} wctype_t; + +static inline wctype_t +wctype (const char *name) +{ + wctype_t i; + static const char names[][10] = { "", + "alnum", "cntrl", "lower", + "space", "alpha", "digit", + "print", "upper", "blank", + "graph", "punct", "xdigit" }; + for (i = GRUB_CTYPE_INVALID; i < GRUB_CTYPE_MAX; i++) + if (grub_strcmp (names[i], name) == 0) + return i; + return GRUB_CTYPE_INVALID; +} + +/* FIXME: take into account international lowercase characters. */ +static inline int +iswlower (wint_t wc) +{ + return grub_islower (wc); +} + +static inline wint_t +towlower (wint_t c) +{ + return grub_tolower (c); +} + +static inline wint_t +towupper (wint_t c) +{ + return grub_toupper (c); +} + +static inline int +iswalnum (wint_t c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + +static inline int +iswctype (wint_t wc, wctype_t desc) +{ + switch (desc) + { + case GRUB_CTYPE_ALNUM: + return iswalnum (wc); + case GRUB_CTYPE_CNTRL: + return grub_iscntrl (wc); + case GRUB_CTYPE_LOWER: + return iswlower (wc); + case GRUB_CTYPE_SPACE: + return grub_isspace (wc); + case GRUB_CTYPE_ALPHA: + return grub_isalpha (wc); + case GRUB_CTYPE_DIGIT: + return grub_isdigit (wc); + case GRUB_CTYPE_PRINT: + return grub_isprint (wc); + case GRUB_CTYPE_UPPER: + return grub_isupper (wc); + case GRUB_CTYPE_BLANK: + return wc == ' ' || wc == '\t'; + case GRUB_CTYPE_GRAPH: + return grub_isgraph (wc); + case GRUB_CTYPE_PUNCT: + return grub_isprint (wc) && !grub_isspace (wc) && !iswalnum (wc); + case GRUB_CTYPE_XDIGIT: + return grub_isxdigit (wc); + default: + return 0; + } +} + +#endif diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index 85ead53c4..d089843cc 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -60,6 +60,51 @@ #include "widthspec.h" #endif +int +grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count) +{ + if (*count) + { + if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) + { + /* invalid */ + return 0; + } + else + { + *code <<= 6; + *code |= (c & GRUB_UINT8_6_TRAILINGBITS); + (*count)--; + return 1; + } + } + + if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) + { + *code = c; + return 1; + } + if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) + { + *count = 1; + *code = c & GRUB_UINT8_5_TRAILINGBITS; + return 1; + } + if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) + { + *count = 2; + *code = c & GRUB_UINT8_4_TRAILINGBITS; + return 1; + } + if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) + { + *count = 3; + *code = c & GRUB_UINT8_3_TRAILINGBITS; + return 1; + } + return 0; +} + grub_ssize_t grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, @@ -74,64 +119,27 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, while (srcsize && destsize) { - grub_uint32_t c = *src++; + grub_uint8_t c = *src++; if (srcsize != (grub_size_t)-1) srcsize--; - if (count) + if (!grub_utf8_process (c, &code, &count)) + return -1; + if (count != 0) + continue; + if (code == 0) + break; + if (destsize < 2 && code >= GRUB_UCS2_LIMIT) + break; + if (code >= GRUB_UCS2_LIMIT) { - if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) - { - /* invalid */ - return -1; - } - else - { - code <<= 6; - code |= (c & GRUB_UINT8_6_TRAILINGBITS); - count--; - } + *p++ = GRUB_UTF16_UPPER_SURROGATE (code); + *p++ = GRUB_UTF16_LOWER_SURROGATE (code); + destsize -= 2; } else { - if (c == 0) - break; - - if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) - code = c; - else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) - { - count = 1; - code = c & GRUB_UINT8_5_TRAILINGBITS; - } - else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) - { - count = 2; - code = c & GRUB_UINT8_4_TRAILINGBITS; - } - else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) - { - count = 3; - code = c & GRUB_UINT8_3_TRAILINGBITS; - } - else - return -1; - } - - if (count == 0) - { - if (destsize < 2 && code >= GRUB_UCS2_LIMIT) - break; - if (code >= GRUB_UCS2_LIMIT) - { - *p++ = GRUB_UTF16_UPPER_SURROGATE (code); - *p++ = GRUB_UTF16_LOWER_SURROGATE (code); - destsize -= 2; - } - else - { - *p++ = code; - destsize--; - } + *p++ = code; + destsize--; } } @@ -140,6 +148,53 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, return p - dest; } +/* Returns -2 if not enough space, -1 on invalid character. */ +grub_ssize_t +grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, + grub_uint32_t code) +{ + if (dest >= destend) + return -2; + if (code <= 0x007F) + { + *dest++ = code; + return 1; + } + if (code <= 0x07FF) + { + if (dest + 1 >= destend) + return -2; + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + return 2; + } + if ((code >= 0xDC00 && code <= 0xDFFF) + || (code >= 0xD800 && code <= 0xDBFF)) + { + /* No surrogates in UCS-4... */ + return -1; + } + if (code < 0x10000) + { + if (dest + 2 >= destend) + return -2; + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + return 3; + } + { + if (dest + 3 >= destend) + return -2; + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + return 4; + } + +} + /* Convert UCS-4 to UTF-8. */ void grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, @@ -151,39 +206,17 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, while (size-- && dest < destend) { grub_uint32_t code = *src++; - - if (code <= 0x007F) - *dest++ = code; - else if (code <= 0x07FF) + grub_ssize_t s; + s = grub_encode_utf8_character (dest, destend, + code); + if (s == -2) + break; + if (s == -1) { - if (dest + 1 >= destend) - break; - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - } - else if ((code >= 0xDC00 && code <= 0xDFFF) - || (code >= 0xD800 && code <= 0xDBFF)) - { - /* No surrogates in UCS-4... */ *dest++ = '?'; + continue; } - else if (code < 0x10000) - { - if (dest + 2 >= destend) - break; - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - else - { - if (dest + 3 >= destend) - break; - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } + dest += s; } *dest = 0; } diff --git a/include/grub/charset.h b/include/grub/charset.h index 13443dad2..c7f86a1ef 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -126,11 +126,22 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, grub_uint32_t **last_position); + +/* Process one character from UTF8 sequence. + At beginning set *code = 0, *count = 0. Returns 0 on failure and + 1 on success. *count holds the number of trailing bytes. */ +int +grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count); + void grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, grub_uint8_t *dest, grub_size_t destsize); grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, const grub_uint8_t **srcend); +/* Returns -2 if not enough space, -1 on invalid character. */ +grub_ssize_t +grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, + grub_uint32_t code); #endif diff --git a/include/grub/misc.h b/include/grub/misc.h index 358f73258..0344d528b 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -175,6 +175,18 @@ grub_isalpha (int c) return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +static inline int +grub_islower (int c) +{ + return (c >= 'a' && c <= 'z'); +} + +static inline int +grub_isupper (int c) +{ + return (c >= 'A' && c <= 'Z'); +} + static inline int grub_isgraph (int c) { @@ -250,27 +262,6 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); } -/* Replace all `ch' characters of `input' with `with' and copy the - result into `output'; return EOS address of `output'. */ -static inline char * -grub_strchrsub (char *output, const char *input, char ch, const char *with) -{ - grub_size_t grub_strlen (const char *s); - while (*input) - { - if (*input == ch) - { - grub_strcpy (output, with); - output += grub_strlen (with); - input++; - continue; - } - *output++ = *input++; - } - *output = '\0'; - return output; -} - unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); @@ -317,6 +308,26 @@ grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) __attribute__ ((warn_unused int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +/* Replace all `ch' characters of `input' with `with' and copy the + result into `output'; return EOS address of `output'. */ +static inline char * +grub_strchrsub (char *output, const char *input, char ch, const char *with) +{ + while (*input) + { + if (*input == ch) + { + grub_strcpy (output, with); + output += grub_strlen (with); + input++; + continue; + } + *output++ = *input++; + } + *output = '\0'; + return output; +} + extern void (*EXPORT_VAR (grub_xputs)) (const char *str); static inline int From cc8f366887c838bce6c74aee45914623076cca4a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 00:55:00 +0100 Subject: [PATCH 247/315] * grub-core/commands/acpi.c (grub_acpi_create_ebda) [!x86]: Disable. (grub_cmd_acpi) [!x86]: Disable EBDA. --- ChangeLog | 5 +++++ grub-core/commands/acpi.c | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91eca49ae..e6a2125dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/commands/acpi.c (grub_acpi_create_ebda) [!x86]: Disable. + (grub_cmd_acpi) [!x86]: Disable EBDA. + 2011-12-13 Vladimir Serbinenko Enable UTF8 in gnulib regexp. diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 8f4429627..f394e3233 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -138,6 +138,7 @@ iszero (grub_uint8_t *reg, int size) return 1; } +#if defined (__i386__) || defined (__x86_64__) grub_err_t grub_acpi_create_ebda (void) { @@ -297,6 +298,7 @@ grub_acpi_create_ebda (void) return GRUB_ERR_NONE; } +#endif /* Create tables common to ACPIv1 and ACPIv2+ */ static void @@ -463,7 +465,6 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) struct grub_arg_list *state = ctxt->state; struct grub_acpi_rsdp_v10 *rsdp; struct efiemu_acpi_table *cur, *t; - grub_err_t err; int i, mmapregion; int numoftables; @@ -732,13 +733,20 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) } acpi_tables = 0; - if (! state[9].set && (err = grub_acpi_create_ebda ())) +#if defined (__i386__) || defined (__x86_64__) + if (! state[9].set) { - rsdpv1_new = 0; - rsdpv2_new = 0; - grub_mmap_free_and_unregister (mmapregion); - return err; + grub_err_t err; + err = grub_acpi_create_ebda (); + if (err) + { + rsdpv1_new = 0; + rsdpv2_new = 0; + grub_mmap_free_and_unregister (mmapregion); + return err; + } } +#endif #ifdef GRUB_MACHINE_EFI { From ee533335f54c938184b782a52ca8a29209491772 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:00:34 +0100 Subject: [PATCH 248/315] * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_finddevice): Make first argument a const pointer. * grub-core/kern/ieee1275/openfw.c (grub_children_iterate): Likewise. * include/grub/ieee1275/ieee1275.h (grub_ieee1275_finddevice): Update proto. (grub_children_iterate): Likewise. (grub_machine_mmap_iterate): Remove redundant declaration. --- ChangeLog | 10 ++++++++++ grub-core/kern/ieee1275/ieee1275.c | 2 +- grub-core/kern/ieee1275/openfw.c | 2 +- include/grub/ieee1275/ieee1275.h | 6 ++---- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6a2125dd..0d92fb424 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_finddevice): Make + first argument a const pointer. + * grub-core/kern/ieee1275/openfw.c (grub_children_iterate): Likewise. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_finddevice): Update + proto. + (grub_children_iterate): Likewise. + (grub_machine_mmap_iterate): Remove redundant declaration. + 2011-12-13 Vladimir Serbinenko * grub-core/commands/acpi.c (grub_acpi_create_ebda) [!x86]: Disable. diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c index b32fd2d8b..b20f64d68 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/grub-core/kern/ieee1275/ieee1275.c @@ -27,7 +27,7 @@ int -grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep) +grub_ieee1275_finddevice (const char *name, grub_ieee1275_phandle_t *phandlep) { struct find_device_args { diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 3568ffe64..ee81b4ef9 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -34,7 +34,7 @@ enum grub_ieee1275_parse_type /* Walk children of 'devpath', calling hook for each. */ int -grub_children_iterate (char *devpath, +grub_children_iterate (const char *devpath, int (*hook) (struct grub_ieee1275_devalias *alias)) { grub_ieee1275_phandle_t dev; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index be3835a42..b84d75697 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -125,7 +125,7 @@ extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag); void EXPORT_FUNC(grub_ieee1275_init) (void); -int EXPORT_FUNC(grub_ieee1275_finddevice) (char *name, +int EXPORT_FUNC(grub_ieee1275_finddevice) (const char *name, grub_ieee1275_phandle_t *phandlep); int EXPORT_FUNC(grub_ieee1275_get_property) (grub_ieee1275_phandle_t phandle, const char *property, void *buf, @@ -184,10 +184,8 @@ int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs); int EXPORT_FUNC(grub_devalias_iterate) (int (*hook) (struct grub_ieee1275_devalias *alias)); -int EXPORT_FUNC(grub_children_iterate) (char *devpath, +int EXPORT_FUNC(grub_children_iterate) (const char *devpath, int (*hook) (struct grub_ieee1275_devalias *alias)); -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); int From 5d048bf210da3c5bc4666f90341461e4703f7dcb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:07:06 +0100 Subject: [PATCH 249/315] * grub-core/net/drivers/ieee1275/ofnet.c (bootp_response_properties): Make name a const ptr. --- ChangeLog | 5 +++++ grub-core/net/drivers/ieee1275/ofnet.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0d92fb424..7198d951f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/net/drivers/ieee1275/ofnet.c (bootp_response_properties): + Make name a const ptr. + 2011-12-13 Vladimir Serbinenko * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_finddevice): Make diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 20d45ee3d..7a1edcc1b 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -106,7 +106,7 @@ static struct grub_net_card_driver ofdriver = static const struct { - char *name; + const char *name; int offset; } From ef6e433586fca0d21ffaa776f84cfd5b463f630e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:19:47 +0100 Subject: [PATCH 250/315] * grub-core/disk/raid.c (scan_devices): Fix condition. --- ChangeLog | 4 ++++ grub-core/disk/raid.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7198d951f..b157a8e40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/disk/raid.c (scan_devices): Fix condition. + 2011-12-13 Vladimir Serbinenko * grub-core/net/drivers/ieee1275/ofnet.c (bootp_response_properties): diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index e4c53e73b..aeba2a22f 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -120,7 +120,7 @@ scan_devices (const char *arname) struct grub_raid_member *m; for (m = arr->members; m < arr->members + arr->nr_devs; m++) if (m->device && m->device->id == disk->id - && m->device->dev->id == m->device->dev->id + && m->device->dev->id == disk->dev->id && grub_partition_get_start (m->device->partition) == grub_partition_get_start (disk->partition) && grub_disk_get_size (m->device) From 496bd07446c4e8a09146004a16971ad37fc973c1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:26:53 +0100 Subject: [PATCH 251/315] Unify and improve RAID and crypto xor. * grub-core/disk/raid.c (grub_raid_block_xor): Removed. All users changed to grub_crypto_xor * grub-core/lib/crypto.c (grub_crypto_xor): Moved from here ... * include/grub/crypto.h (grub_crypto_xor): ... here. Inlined. Use bigger types when possible. --- ChangeLog | 10 ++++++++++ grub-core/disk/raid.c | 17 ---------------- grub-core/disk/raid5_recover.c | 3 ++- grub-core/disk/raid6_recover.c | 15 +++++++------- grub-core/lib/crypto.c | 14 ------------- include/grub/crypto.h | 36 ++++++++++++++++++++++++++++++++-- 6 files changed, 54 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index b157a8e40..801681ef5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-12-13 Vladimir Serbinenko + + Unify and improve RAID and crypto xor. + + * grub-core/disk/raid.c (grub_raid_block_xor): Removed. All users + changed to grub_crypto_xor + * grub-core/lib/crypto.c (grub_crypto_xor): Moved from here ... + * include/grub/crypto.h (grub_crypto_xor): ... here. Inlined. + Use bigger types when possible. + 2011-12-13 Vladimir Serbinenko * grub-core/disk/raid.c (scan_devices): Fix condition. diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index aeba2a22f..db1e969b3 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -332,23 +332,6 @@ grub_raid_close (grub_disk_t disk __attribute ((unused))) return; } -void -grub_raid_block_xor (char *buf1, const char *buf2, int size) -{ - grub_size_t *p1; - const grub_size_t *p2; - - p1 = (grub_size_t *) buf1; - p2 = (const grub_size_t *) buf2; - size /= GRUB_CPU_SIZEOF_VOID_P; - - while (size) - { - *(p1++) ^= *(p2++); - size--; - } -} - static grub_err_t grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) diff --git a/grub-core/disk/raid5_recover.c b/grub-core/disk/raid5_recover.c index c26d05e94..dfc89a71d 100644 --- a/grub-core/disk/raid5_recover.c +++ b/grub-core/disk/raid5_recover.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -57,7 +58,7 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr, return err; } - grub_raid_block_xor (buf, buf2, size); + grub_crypto_xor (buf, buf2, buf2, size); } grub_free (buf2); diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index e91992547..05d8511c5 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -98,9 +99,9 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, array->members[pos].start_sector + sector, 0, size, buf))) { - grub_raid_block_xor (pbuf, buf, size); + grub_crypto_xor (pbuf, pbuf, buf, size); grub_raid_block_mulx (i, buf, size); - grub_raid_block_xor (qbuf, buf, size); + grub_crypto_xor (qbuf, qbuf, buf, size); } else { @@ -130,7 +131,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, array->members[p].start_sector + sector, 0, size, buf))) { - grub_raid_block_xor (buf, pbuf, size); + grub_crypto_xor (buf, buf, pbuf, size); goto quit; } @@ -145,7 +146,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, array->members[q].start_sector + sector, 0, size, buf)) goto quit; - grub_raid_block_xor (buf, qbuf, size); + grub_crypto_xor (buf, buf, qbuf, size); grub_raid_block_mulx (255 - bad1, buf, size); } @@ -165,14 +166,14 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, 0, size, buf)) goto quit; - grub_raid_block_xor (pbuf, buf, size); + grub_crypto_xor (pbuf, pbuf, buf, size); if (grub_disk_read (array->members[q].device, array->members[q].start_sector + sector, 0, size, buf)) goto quit; - grub_raid_block_xor (qbuf, buf, size); + grub_crypto_xor (qbuf, qbuf, buf, size); c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255; grub_raid_block_mulx (c, qbuf, size); @@ -180,7 +181,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, c = (bad2 + c) % 255; grub_raid_block_mulx (c, pbuf, size); - grub_raid_block_xor (pbuf, qbuf, size); + grub_crypto_xor (pbuf, pbuf, qbuf, size); grub_memcpy (buf, pbuf, size); } diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 4dec5c694..48d860335 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -169,20 +169,6 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, return cipher->cipher->setkey (cipher->ctx, key, keylen); } -void -grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size) -{ - const grub_uint8_t *in1ptr = in1, *in2ptr = in2; - grub_uint8_t *outptr = out; - while (size--) - { - *outptr = *in1ptr ^ *in2ptr; - in1ptr++; - in2ptr++; - outptr++; - } -} - gcry_err_code_t grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, void *out, const void *in, grub_size_t size) diff --git a/include/grub/crypto.h b/include/grub/crypto.h index b8a5b3a22..9a67c5e11 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -198,8 +198,40 @@ 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); +static inline void +grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size) +{ + const grub_uint8_t *in1ptr = in1, *in2ptr = in2; + grub_uint8_t *outptr = out; + while (size && (((grub_addr_t) in1ptr & (sizeof (grub_uint64_t) - 1)) + || ((grub_addr_t) in2ptr & (sizeof (grub_uint64_t) - 1)) + || ((grub_addr_t) outptr & (sizeof (grub_uint64_t) - 1)))) + { + *outptr = *in1ptr ^ *in2ptr; + in1ptr++; + in2ptr++; + outptr++; + size--; + } + while (size >= sizeof (grub_uint64_t)) + { + *(grub_uint64_t *) (void *) outptr + = (*(grub_uint64_t *) (void *) in1ptr + ^ *(grub_uint64_t *) (void *) in2ptr); + in1ptr += sizeof (grub_uint64_t); + in2ptr += sizeof (grub_uint64_t); + outptr += sizeof (grub_uint64_t); + size -= sizeof (grub_uint64_t); + } + while (size) + { + *outptr = *in1ptr ^ *in2ptr; + in1ptr++; + in2ptr++; + outptr++; + size--; + } +} gcry_err_code_t grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, From 055dc23978de3a439d6f3481a547d27b31e4b790 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:32:41 +0100 Subject: [PATCH 252/315] * grub-core/kern/emu/main.c (main): Add missing const qualifier. * grub-core/loader/efi/appleloader.c (devdata): Likewise. --- ChangeLog | 5 +++++ grub-core/kern/emu/main.c | 2 +- grub-core/loader/efi/appleloader.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 801681ef5..f14ce3de2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/kern/emu/main.c (main): Add missing const qualifier. + * grub-core/loader/efi/appleloader.c (devdata): Likewise. + 2011-12-13 Vladimir Serbinenko Unify and improve RAID and crypto xor. diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 725d1ac7f..64e72dff6 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -127,7 +127,7 @@ void grub_emu_init (void); int main (int argc, char *argv[]) { - char *dev_map = DEFAULT_DEVICE_MAP; + const char *dev_map = DEFAULT_DEVICE_MAP; volatile int hold = 0; int opt; diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index db57a573c..d0211a80f 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -126,7 +126,7 @@ static struct piwg_full_device_path devpath_6 = MAKE_PIWG_PATH (0xffcc4000, struct devdata { - char *model; + const char *model; grub_efi_device_path_t *devpath; }; From 53072f9b96ae2333382f64df95198d7bb1e5227d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:36:09 +0100 Subject: [PATCH 253/315] * grub-core/term/at_keyboard.c (set_scancodes): Fix preprocessor conditionals. --- ChangeLog | 5 +++++ grub-core/term/at_keyboard.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f14ce3de2..088f6f848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (set_scancodes): Fix preprocessor + conditionals. + 2011-12-13 Vladimir Serbinenko * grub-core/kern/emu/main.c (main): Add missing const qualifier. diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index b81e76230..bcd20d3ff 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -332,10 +332,10 @@ set_scancodes (void) return; } -#if !(defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU)) +#if !(defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS)) current_set = 1; return; -#endif +#else grub_keyboard_controller_write (grub_keyboard_controller_orig & ~KEYBOARD_AT_TRANSLATE); @@ -352,6 +352,7 @@ set_scancodes (void) if (current_set == 1) return; grub_printf ("No supported scancode set found\n"); +#endif } static void From 78c2cd1c627e58ac102dc03dbf811f03c8d1c9d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:41:16 +0100 Subject: [PATCH 254/315] * grub-core/fs/udf.c (read_string): Macroify GRUB_MAX_UTF8_PER_UTF16. * grub-core/fs/jfs.c (grub_jfs_diropen): Likewise. * grub-core/fs/fat.c (grub_fat_iterate_dir): Likewise. --- ChangeLog | 6 ++++++ grub-core/fs/fat.c | 4 ++-- grub-core/fs/jfs.c | 2 +- grub-core/fs/udf.c | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 088f6f848..0780a3691 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/udf.c (read_string): Macroify GRUB_MAX_UTF8_PER_UTF16. + * grub-core/fs/jfs.c (grub_jfs_diropen): Likewise. + * grub-core/fs/fat.c (grub_fat_iterate_dir): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/term/at_keyboard.c (set_scancodes): Fix preprocessor diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 0d32e229d..0569120fb 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -589,7 +589,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, char *filename; unibuf = grub_malloc (15 * 256 * 2); - filename = grub_malloc (15 * 256 * 4 + 1); + filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1); while (1) { @@ -696,7 +696,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); /* Allocate space enough to hold a long name. */ - filename = grub_malloc (0x40 * 13 * 4 + 1); + filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1); unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2); if (! filename || ! unibuf) { diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 91497f143..3554803cb 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -241,7 +241,7 @@ struct grub_jfs_diropen /* On-disk name is at most 255 UTF-16 codepoints. Every UTF-16 codepoint is at most 4 UTF-8 bytes. */ - char name[256 * 4 + 1]; + char name[256 * GRUB_MAX_UTF8_PER_UTF16 + 1]; grub_uint32_t ino; } __attribute__ ((packed)); diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index e1f115015..4097fd2e6 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -820,7 +820,7 @@ read_string (grub_uint8_t *raw, grub_size_t sz) for (i = 0; i < utf16len; i++) utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; } - ret = grub_malloc (utf16len * 3 + 1); + ret = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); if (ret) *grub_utf16_to_utf8 ((grub_uint8_t *) ret, utf16, utf16len) = '\0'; grub_free (utf16); From 47ae27ec75ff54acd8a04cdda20069092e9e0f74 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:45:38 +0100 Subject: [PATCH 255/315] * grub-core/normal/datetime.c (grub_weekday_names): Make const. --- ChangeLog | 4 ++++ grub-core/normal/datetime.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0780a3691..fd7add031 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/normal/datetime.c (grub_weekday_names): Make const. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/udf.c (read_string): Macroify GRUB_MAX_UTF8_PER_UTF16. diff --git a/grub-core/normal/datetime.c b/grub-core/normal/datetime.c index 8183601ba..bbc2cdea9 100644 --- a/grub-core/normal/datetime.c +++ b/grub-core/normal/datetime.c @@ -20,7 +20,7 @@ #include #include -static const char *grub_weekday_names[] = +static const char *const grub_weekday_names[] = { N_("Sunday"), N_("Monday"), From 1f313b942bb509d4a17a2f78b6d077ccbe7eb93f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:54:59 +0100 Subject: [PATCH 256/315] * include/grub/types.h (grub_properly_aligned_t): New type. (GRUB_PROPERLY_ALIGNED_ARRAY): New macro. (grub_get_unaligned16): Add explicit casts. (grub_get_unaligned32): Likewise. (grub_get_unaligned64): Likewise. (grub_set_unaligned16): New function. (grub_set_unaligned32): Likewise. --- ChangeLog | 10 +++++++ include/grub/types.h | 66 ++++++++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd7add031..c64fe07b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/types.h (grub_properly_aligned_t): New type. + (GRUB_PROPERLY_ALIGNED_ARRAY): New macro. + (grub_get_unaligned16): Add explicit casts. + (grub_get_unaligned32): Likewise. + (grub_get_unaligned64): Likewise. + (grub_set_unaligned16): New function. + (grub_set_unaligned32): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/normal/datetime.c (grub_weekday_names): Make const. diff --git a/include/grub/types.h b/include/grub/types.h index f057dd3d3..e61a9a5c6 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -140,6 +140,10 @@ typedef grub_int32_t grub_ssize_t; #define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x)) #endif +typedef grub_uint64_t grub_properly_aligned_t; + +#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[(size + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] + /* The type for representing a file offset. */ typedef grub_uint64_t grub_off_t; @@ -222,31 +226,57 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x)) #endif /* ! WORDS_BIGENDIAN */ -static inline grub_uint16_t grub_get_unaligned16(void *ptr) +static inline grub_uint16_t grub_get_unaligned16 (const void *ptr) { - struct - { - grub_uint16_t d; - } __attribute__((packed)) *dd = ptr; - return dd->d; + struct grub_unaligned_uint16_t + { + grub_uint16_t d; + } __attribute__ ((packed)); + const struct grub_unaligned_uint16_t *dd + = (const struct grub_unaligned_uint16_t *) ptr; + return dd->d; } -static inline grub_uint32_t grub_get_unaligned32(void *ptr) +static inline void grub_set_unaligned16 (void *ptr, grub_uint16_t val) { - struct - { - grub_uint32_t d; - } __attribute__((packed)) *dd = ptr; - return dd->d; + struct grub_unaligned_uint16_t + { + grub_uint16_t d; + } __attribute__ ((packed)); + struct grub_unaligned_uint16_t *dd = (struct grub_unaligned_uint16_t *) ptr; + dd->d = val; } -static inline grub_uint64_t grub_get_unaligned64(void *ptr) +static inline grub_uint32_t grub_get_unaligned32 (const void *ptr) { - struct - { - grub_uint64_t d; - } __attribute__((packed)) *dd = ptr; - return dd->d; + struct grub_unaligned_uint32_t + { + grub_uint32_t d; + } __attribute__ ((packed)); + const struct grub_unaligned_uint32_t *dd + = (const struct grub_unaligned_uint32_t *) ptr; + return dd->d; +} + +static inline void grub_set_unaligned32 (void *ptr, grub_uint32_t val) +{ + struct grub_unaligned_uint32_t + { + grub_uint32_t d; + } __attribute__ ((packed)); + struct grub_unaligned_uint32_t *dd = (struct grub_unaligned_uint32_t *) ptr; + dd->d = val; +} + +static inline grub_uint64_t grub_get_unaligned64 (const void *ptr) +{ + struct grub_unaligned_uint64_t + { + grub_uint64_t d; + } __attribute__ ((packed)); + const struct grub_unaligned_uint64_t *dd + = (const struct grub_unaligned_uint64_t *)ptr; + return dd->d; } #endif /* ! GRUB_TYPES_HEADER */ From 20993fbb9f820ecd0d9245c64574b5333d330779 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:57:07 +0100 Subject: [PATCH 257/315] * grub-core/fs/romfs.c (grub_romfs_iterate_dir): Properly align name for checksum and fix allocation algorithm. --- ChangeLog | 5 +++++ grub-core/fs/romfs.c | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index c64fe07b7..086b61ff9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/romfs.c (grub_romfs_iterate_dir): Properly align + name for checksum and fix allocation algorithm. + 2011-12-13 Vladimir Serbinenko * include/grub/types.h (grub_properly_aligned_t): New type. diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 202ca102e..76e13727d 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -166,17 +166,18 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, { grub_disk_addr_t caddr; struct grub_romfs_file_header hdr; - grub_size_t a = 0; - char *name = NULL; unsigned nptr; unsigned i, j; + grub_size_t a = 0; + grub_properly_aligned_t *name = NULL; + for (caddr = dir->data_addr; caddr; caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1)) { grub_disk_addr_t naddr = caddr + sizeof (hdr); grub_uint32_t csum = 0; enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN; - struct grub_fshelp_node *node; + struct grub_fshelp_node *node = NULL; grub_err_t err; err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS, @@ -189,9 +190,9 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, } for (nptr = 0; ; nptr++, naddr += 16) { - if (a >= nptr) + if (a <= nptr) { - char *on; + grub_properly_aligned_t *on; a = 2 * (nptr + 1); on = name; name = grub_realloc (name, a * 16); @@ -201,13 +202,14 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, return 1; } } + COMPILE_TIME_ASSERT (16 % sizeof (name[0]) == 0); err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS, naddr & (GRUB_DISK_SECTOR_SIZE - 1), - 16, name + 16 * nptr); + 16, name + (16 / sizeof (name[0])) * nptr); if (err) return 1; for (j = 0; j < 16; j++) - if (!name[16 * nptr + j]) + if (!((char *) name)[16 * nptr + j]) break; if (j != 16) break; @@ -292,7 +294,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, } } - if (hook (name, filetype, node)) + if (hook ((char *) name, filetype, node)) { grub_free (name); return 1; From 812e249302778f6b0709f33578be111e219c6263 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 01:58:35 +0100 Subject: [PATCH 258/315] * grub-core/fs/ext2.c (grub_ext4_find_leaf): MAke buf as pointer to properly aligned memory. (grub_ext2_read_block): Ensure buffer alignment. --- ChangeLog | 6 ++++++ grub-core/fs/ext2.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 086b61ff9..99fcb1f95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/ext2.c (grub_ext4_find_leaf): MAke buf as pointer to + properly aligned memory. + (grub_ext2_read_block): Ensure buffer alignment. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/romfs.c (grub_romfs_iterate_dir): Properly align diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c index 0fdf151a2..6eb53d3f8 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -337,7 +337,7 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group, } static struct grub_ext4_extent_header * -grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf, +grub_ext4_find_leaf (struct grub_ext2_data *data, grub_properly_aligned_t *buf, struct grub_ext4_extent_header *ext_block, grub_uint32_t fileblock) { @@ -387,7 +387,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG) { - char buf[EXT2_BLOCK_SIZE(data)]; + GRUB_PROPERLY_ALIGNED_ARRAY (buf, EXT2_BLOCK_SIZE(data)); struct grub_ext4_extent_header *leaf; struct grub_ext4_extent *ext; int i; From eb561f31234767d9a0f247350bbdb25eb45489fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:00:44 +0100 Subject: [PATCH 259/315] * grub-core/fs/nilfs2.c (grub_nilfs2_btree_node): Add zero-size keys array. (grub_nilfs2_btree_node_dkeys): Ensure return pointer alignment. (grub_nilfs2_btree_lookup): Ensure buffer alignment. --- ChangeLog | 7 +++++++ grub-core/fs/nilfs2.c | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99fcb1f95..1fe654de5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/nilfs2.c (grub_nilfs2_btree_node): Add zero-size keys + array. + (grub_nilfs2_btree_node_dkeys): Ensure return pointer alignment. + (grub_nilfs2_btree_lookup): Ensure buffer alignment. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/ext2.c (grub_ext4_find_leaf): MAke buf as pointer to diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 35a040b97..0b001eb0e 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -208,6 +208,7 @@ struct grub_nilfs2_btree_node grub_uint8_t bn_level; grub_uint16_t bn_nchildren; grub_uint32_t bn_pad; + grub_uint64_t keys[0]; }; struct grub_nilfs2_palloc_group_desc @@ -399,9 +400,9 @@ grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node) static inline grub_uint64_t * grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node) { - return (grub_uint64_t *) ((char *) (node + 1) + - ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? - 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); + return (node->keys + + ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? + 0 : (NILFS_BTREE_NODE_EXTRA_PAD_SIZE / sizeof (grub_uint64_t)))); } static inline grub_uint64_t @@ -502,7 +503,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, grub_uint64_t key, int need_translate) { struct grub_nilfs2_btree_node *node; - unsigned char block[NILFS2_BLOCK_SIZE (data)]; + GRUB_PROPERLY_ALIGNED_ARRAY (block, NILFS2_BLOCK_SIZE (data)); grub_uint64_t ptr; int level, found, index; From 728cba91d205037ae906daa922573034fe89b5ee Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:02:38 +0100 Subject: [PATCH 260/315] * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Use grub_get_unaligned16 to get freetag and skip. --- ChangeLog | 5 +++++ grub-core/fs/xfs.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fe654de5..f83c57348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Use grub_get_unaligned16 + to get freetag and skip. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/nilfs2.c (grub_nilfs2_btree_node): Add zero-size keys diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index c7ce3aac9..fbadc8fa5 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -589,18 +589,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - (int) sizeof (struct grub_xfs_dir2_entry))) { struct grub_xfs_dir2_entry *direntry; - grub_uint16_t *freetag; + grub_uint8_t *freetag; char *filename; direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos]; - freetag = (grub_uint16_t *) direntry; + freetag = (grub_uint8_t *) direntry; - if (*freetag == 0XFFFF) + if (grub_get_unaligned16 (freetag) == 0XFFFF) { - grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1); + grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t)); /* This entry is not used, go to the next one. */ - pos += grub_be_to_cpu16 (*skip); + pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip)); continue; } From 4c5f3056c23933963e3bb052d20508511627a3c0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:05:58 +0100 Subject: [PATCH 261/315] * grub-core/fs/hfsplus.c (grub_hfsplus_btree_recoffset): Handle the case of aunaligned recptr. (grub_hfsplus_read_block): Declare extoverflow as key to ensure alignment. (grub_hfsplus_btree_search): Handle unaligned index. --- ChangeLog | 8 ++++++++ grub-core/fs/hfsplus.c | 25 ++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f83c57348..cbe2c13f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/hfsplus.c (grub_hfsplus_btree_recoffset): Handle the + case of aunaligned recptr. + (grub_hfsplus_read_block): Declare extoverflow as key to ensure + alignment. + (grub_hfsplus_btree_search): Handle unaligned index. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Use grub_get_unaligned16 diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 9d5f20181..7e859be41 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -251,10 +251,9 @@ grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *node, int index) { char *cnode = (char *) node; - grub_uint16_t *recptr; - recptr = (grub_uint16_t *) (&cnode[btree->nodesize - - index * sizeof (grub_uint16_t) - 2]); - return grub_be_to_cpu16 (*recptr); + void *recptr; + recptr = (&cnode[btree->nodesize - index * sizeof (grub_uint16_t) - 2]); + return grub_be_to_cpu16 (grub_get_unaligned16 (recptr)); } /* Return a pointer to the record with the index INDEX, in the node @@ -315,7 +314,7 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) while (1) { struct grub_hfsplus_extkey *key; - struct grub_hfsplus_extkey_internal extoverflow; + struct grub_hfsplus_key_internal extoverflow; grub_disk_addr_t blk; grub_off_t ptr; @@ -343,11 +342,11 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } /* Set up the key to look for in the extent overflow file. */ - extoverflow.fileid = node->fileid; - extoverflow.start = fileblock - blksleft; + extoverflow.extkey.fileid = node->fileid; + extoverflow.extkey.start = fileblock - blksleft; if (grub_hfsplus_btree_search (&node->data->extoverflow_tree, - (struct grub_hfsplus_key_internal *) &extoverflow, + &extoverflow, grub_hfsplus_cmp_extkey, &nnode, &ptr)) { grub_error (GRUB_ERR_READ_ERROR, @@ -697,7 +696,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, } else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX) { - grub_uint32_t *pointer; + void *pointer; /* The place where the key could have been found didn't contain the key. This means that the previous match @@ -709,10 +708,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, that we are looking for. The last match that is found will be used to locate the child which can contain the record. */ - pointer = (grub_uint32_t *) ((char *) currkey - + grub_be_to_cpu16 (currkey->keylen) - + 2); - currnode = grub_be_to_cpu32 (*pointer); + pointer = ((char *) currkey + + grub_be_to_cpu16 (currkey->keylen) + + 2); + currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer)); match = 1; } } From d1c930f99be8b836eea675232dc5628f7e9d8a46 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:08:14 +0100 Subject: [PATCH 262/315] * include/grub/list.h: Explicitly cast return of grub_bad_type_cast to match types. --- ChangeLog | 5 +++++ include/grub/list.h | 16 +++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbe2c13f5..672bb9dd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/list.h: Explicitly cast return of grub_bad_type_cast + to match types. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/hfsplus.c (grub_hfsplus_btree_recoffset): Handle the diff --git a/include/grub/list.h b/include/grub/list.h index 75353010c..3dfb97ac6 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -54,11 +54,11 @@ grub_bad_type_cast_real (int line, const char *file) #define GRUB_AS_LIST(ptr) \ (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \ - (grub_list_t) ptr : grub_bad_type_cast ()) + (grub_list_t) ptr : (grub_list_t) grub_bad_type_cast ()) #define GRUB_AS_LIST_P(pptr) \ (GRUB_FIELD_MATCH (*pptr, grub_list_t, next) ? \ - (grub_list_t *) (void *) pptr : grub_bad_type_cast ()) + (grub_list_t *) (void *) pptr : (grub_list_t *) grub_bad_type_cast ()) struct grub_named_list { @@ -73,12 +73,12 @@ void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head, #define GRUB_AS_NAMED_LIST(ptr) \ ((GRUB_FIELD_MATCH (ptr, grub_named_list_t, next) && \ GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \ - (grub_named_list_t) ptr : grub_bad_type_cast ()) + (grub_named_list_t) ptr : (grub_named_list_t) grub_bad_type_cast ()) #define GRUB_AS_NAMED_LIST_P(pptr) \ ((GRUB_FIELD_MATCH (*pptr, grub_named_list_t, next) && \ GRUB_FIELD_MATCH (*pptr, grub_named_list_t, name))? \ - (grub_named_list_t *) (void *) pptr : grub_bad_type_cast ()) + (grub_named_list_t *) (void *) pptr : (grub_named_list_t *) grub_bad_type_cast ()) #define GRUB_PRIO_LIST_PRIO_MASK 0xff #define GRUB_PRIO_LIST_FLAG_ACTIVE 0x100 @@ -106,12 +106,14 @@ grub_prio_list_remove (grub_prio_list_t *head, grub_prio_list_t item) ((GRUB_FIELD_MATCH (ptr, grub_prio_list_t, next) && \ GRUB_FIELD_MATCH (ptr, grub_prio_list_t, name) && \ GRUB_FIELD_MATCH (ptr, grub_prio_list_t, prio))? \ - (grub_prio_list_t) ptr : grub_bad_type_cast ()) + (grub_prio_list_t) ptr \ + : (grub_prio_list_t) grub_bad_type_cast ()) #define GRUB_AS_PRIO_LIST_P(pptr) \ ((GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, next) && \ GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, name) && \ - GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, prio))? \ - (grub_prio_list_t *) (void *) pptr : grub_bad_type_cast ()) + GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, prio)) ? \ + (grub_prio_list_t *) (void *) pptr \ + : (grub_prio_list_t *) grub_bad_type_cast ()) #endif /* ! GRUB_LIST_HEADER */ From 9b40df20c4995d81c030eff116661156dd382dfe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:12:23 +0100 Subject: [PATCH 263/315] * include/grub/efiemu/efiemu.h (grub_efiemu_get_memory_map): Remove redundant declaration. (grub_efiemu_mm_obtain_request): Likewise. (grub_efiemu_prepare): Likewise. --- ChangeLog | 7 +++++++ include/grub/efiemu/efiemu.h | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 672bb9dd2..99f8a7bbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/efiemu/efiemu.h (grub_efiemu_get_memory_map): Remove + redundant declaration. + (grub_efiemu_mm_obtain_request): Likewise. + (grub_efiemu_prepare): Likewise. + 2011-12-13 Vladimir Serbinenko * include/grub/list.h: Explicitly cast return of grub_bad_type_cast diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 7b9551627..ec35dac5a 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -200,15 +200,9 @@ grub_efiemu_register_configuration_table (grub_efi_guid_t guid, int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size, grub_efi_memory_type_t type); void *grub_efiemu_mm_obtain_request (int handle); -int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size, - grub_efi_memory_descriptor_t *memory_map, - grub_efi_uintn_t *map_key, - grub_efi_uintn_t *descriptor_size, - grub_efi_uint32_t *descriptor_version); grub_err_t grub_efiemu_mm_unload (void); grub_err_t grub_efiemu_mm_do_alloc (void); grub_err_t grub_efiemu_mm_init (void); -void *grub_efiemu_mm_obtain_request (int handle); void grub_efiemu_mm_return_request (int handle); grub_efi_memory_type_t grub_efiemu_mm_get_type (int handle); @@ -271,7 +265,6 @@ grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value, int minus_handle, int ptv_needed, int size); grub_err_t grub_efiemu_write_sym_markers (void); grub_err_t grub_efiemu_pnvram (void); -grub_err_t grub_efiemu_prepare (void); const char *grub_efiemu_get_default_core_name (void); void grub_efiemu_pnvram_cmd_unregister (void); grub_err_t grub_efiemu_autocore (void); From 564840dc3d7a3588d2b5f695eb8bc7c0f718748f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:13:44 +0100 Subject: [PATCH 264/315] * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Change pointer arithmetic to conserve alignment invariants. --- ChangeLog | 5 +++++ grub-core/disk/mdraid_linux.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99f8a7bbe..b7a5b02f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Change pointer + arithmetic to conserve alignment invariants. + 2011-12-13 Vladimir Serbinenko * include/grub/efiemu/efiemu.h (grub_efiemu_get_memory_map): Remove diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 0e2d85009..7ee513d26 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -216,11 +216,11 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9; array->index = grub_le_to_cpu32 (sb.this_disk.number); array->uuid_len = 16; - array->uuid = grub_malloc (16); + uuid = grub_malloc (16); + array->uuid = (char *) uuid; if (!array->uuid) return grub_errno; - uuid = (grub_uint32_t *) array->uuid; uuid[0] = grub_swap_bytes32 (sb.set_uuid0); uuid[1] = grub_swap_bytes32 (sb.set_uuid1); uuid[2] = grub_swap_bytes32 (sb.set_uuid2); From f138623a601f3fffd09e8a2c21cff36566948319 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 02:15:09 +0100 Subject: [PATCH 265/315] * grub-core/net/netbuff.c (grub_netbuff_alloc): Ensure proper alignment. --- ChangeLog | 4 ++++ grub-core/net/netbuff.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b7a5b02f3..be4b26ba2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/net/netbuff.c (grub_netbuff_alloc): Ensure proper alignment. + 2011-12-13 Vladimir Serbinenko * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Change pointer diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index d20104ab0..bee207f90 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -78,6 +78,8 @@ grub_netbuff_alloc (grub_size_t len) struct grub_net_buff *nb; void *data; + COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0); + if (len < NETBUFFMINLEN) len = NETBUFFMINLEN; @@ -85,7 +87,8 @@ grub_netbuff_alloc (grub_size_t len) data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); if (!data) return NULL; - nb = (struct grub_net_buff *) ((grub_uint8_t *) data + len); + nb = (struct grub_net_buff *) ((grub_properly_aligned_t *) data + + len / sizeof (grub_properly_aligned_t)); nb->head = nb->data = nb->tail = data; nb->end = (char *) nb; return nb; From fcd232b74e605e59ab77a120a26276f5988d2eaf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 11:33:02 +0100 Subject: [PATCH 266/315] * grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline function. (ZAP_HASH_IDX): Likewise. (ZAP_LEAF_HASH_SHIFT): Likewise. (ZAP_LEAF_HASH_NUMENTRIES): Likewise. (LEAF_HASH): Likewise. (ZAP_LEAF_NUMCHUNKS): Likewise. (ZAP_LEAF_CHUNK): Likewise. Changed pointer arithmetic to preserve alignment invariants. Return pointer. All users updated. (ZAP_LEAF_ENTRY): Make into inline function. (NBBY): Removed. (xor): LIkewise. (xor_out): Use grub_crypto_xor. (dnode_get_path): Use grub_get_unaligned. (nvlist_find_value): Likewise. (grub_zfs_nvlist_lookup_uint64): Likewise. (grub_zfs_nvlist_lookup_string): Likewise. (get_nvlist_size): Likewise. (grub_zfs_open): Likewise. (fill_fs_info): Likewise. (grub_zfs_dir): Likewise. * include/grub/zfs/zap_leaf.h (zap_leaf_phys): Adapt to preserve alignment invariants. * include/grub/zfs/zio.h (zio_eck_t): Mark as packed as it's not necessarily aligned. --- ChangeLog | 28 +++++++++ grub-core/fs/zfs/zfs.c | 118 ++++++++++++++++++++++-------------- include/grub/zfs/zap_leaf.h | 3 +- include/grub/zfs/zio.h | 2 +- 4 files changed, 104 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index be4b26ba2..fa3c04c63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline + function. + (ZAP_HASH_IDX): Likewise. + (ZAP_LEAF_HASH_SHIFT): Likewise. + (ZAP_LEAF_HASH_NUMENTRIES): Likewise. + (LEAF_HASH): Likewise. + (ZAP_LEAF_NUMCHUNKS): Likewise. + (ZAP_LEAF_CHUNK): Likewise. Changed pointer arithmetic to preserve + alignment invariants. Return pointer. All users updated. + (ZAP_LEAF_ENTRY): Make into inline function. + (NBBY): Removed. + (xor): LIkewise. + (xor_out): Use grub_crypto_xor. + (dnode_get_path): Use grub_get_unaligned. + (nvlist_find_value): Likewise. + (grub_zfs_nvlist_lookup_uint64): Likewise. + (grub_zfs_nvlist_lookup_string): Likewise. + (get_nvlist_size): Likewise. + (grub_zfs_open): Likewise. + (fill_fs_info): Likewise. + (grub_zfs_dir): Likewise. + * include/grub/zfs/zap_leaf.h (zap_leaf_phys): Adapt to preserve + alignment invariants. + * include/grub/zfs/zio.h (zio_eck_t): Mark as packed as it's not + necessarily aligned. + 2011-12-13 Vladimir Serbinenko * grub-core/net/netbuff.c (grub_netbuff_alloc): Ensure proper alignment. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9de2ab586..534b7d224 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -77,14 +77,23 @@ static grub_dl_t my_mod; #endif #define P2PHASE(x, align) ((x) & ((align) - 1)) -#define DVA_OFFSET_TO_PHYS_SECTOR(offset) \ - ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT) + +static inline grub_disk_addr_t +DVA_OFFSET_TO_PHYS_SECTOR (grub_disk_addr_t offset) +{ + return ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT); +} /* * FAT ZAP data structures */ #define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ -#define ZAP_HASH_IDX(hash, n) (((n) == 0) ? 0 : ((hash) >> (64 - (n)))) +static inline grub_uint64_t +ZAP_HASH_IDX (grub_uint64_t hash, grub_uint64_t n) +{ + return (((n) == 0) ? 0 : ((hash) >> (64 - (n)))); +} + #define CHAIN_END 0xffff /* end of the chunk chain */ /* @@ -93,37 +102,60 @@ static grub_dl_t my_mod; */ #define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) -#define ZAP_LEAF_HASH_SHIFT(bs) (bs - 5) -#define ZAP_LEAF_HASH_NUMENTRIES(bs) (1 << ZAP_LEAF_HASH_SHIFT(bs)) -#define LEAF_HASH(bs, h) \ - ((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) & \ - ((h) >> (64 - ZAP_LEAF_HASH_SHIFT(bs)-l->l_hdr.lh_prefix_len))) +static inline int +ZAP_LEAF_HASH_SHIFT (int bs) +{ + return bs - 5; +} + +static inline int +ZAP_LEAF_HASH_NUMENTRIES (int bs) +{ + return 1 << ZAP_LEAF_HASH_SHIFT(bs); +} + +static inline grub_size_t +LEAF_HASH (int bs, grub_uint64_t h, zap_leaf_phys_t *l) +{ + return ((ZAP_LEAF_HASH_NUMENTRIES (bs)-1) + & ((h) >> (64 - ZAP_LEAF_HASH_SHIFT (bs) - l->l_hdr.lh_prefix_len))); +} /* * The amount of space available for chunks is: * block size shift - hash entry size (2) * number of hash * entries - header space (2*chunksize) */ -#define ZAP_LEAF_NUMCHUNKS(bs) \ - (((1<l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx] -#define ZAP_LEAF_ENTRY(l, bs, idx) (&ZAP_LEAF_CHUNK(l, bs, idx).l_entry) +static inline zap_leaf_chunk_t * +ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx) +{ + return &((zap_leaf_chunk_t *) (l->l_entries + + (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2) + / sizeof (grub_properly_aligned_t)))[idx]; +} + +static inline struct zap_leaf_entry * +ZAP_LEAF_ENTRY(zap_leaf_phys_t *l, int bs, int idx) +{ + return &ZAP_LEAF_CHUNK(l, bs, idx)->l_entry; +} /* * Decompression Entry - lzjb */ -#ifndef NBBY -#define NBBY 8 -#endif extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); @@ -969,14 +1001,6 @@ scan_devices (struct grub_zfs_data *data) return GRUB_ERR_NONE; } -static inline void -xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s) -{ - s /= sizeof (grub_uint64_t); - while (s--) - *a++ ^= *b++; -} - /* x**y. */ static grub_uint8_t powx[255 * 2]; /* Such an s that x**s = y */ @@ -985,17 +1009,15 @@ static const grub_uint8_t poly = 0x1d; /* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */ static inline void -xor_out (void *a_in, const void *b_in, grub_size_t s, +xor_out (grub_uint8_t *a, const grub_uint8_t *b, grub_size_t s, int known_idx, int recovery_pow) { int add; - grub_uint8_t *a = a_in; - const grub_uint8_t *b = b_in; /* Simple xor. */ if (known_idx == 0 || recovery_pow == 0) { - xor (a_in, b_in, s); + grub_crypto_xor (a, a, b, s); return; } add = (known_idx * recovery_pow) % 255; @@ -1827,7 +1849,7 @@ zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, while (bseen < array_len) { - struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; + struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array; int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) @@ -1851,7 +1873,7 @@ zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, while (bseen < array_len) { - struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; + struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array; int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) @@ -1887,7 +1909,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); - for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian); + for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian); chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian)) { @@ -1917,7 +1939,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; + la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk)->l_array; *value = grub_be_to_cpu64 (la->la_array64); @@ -2552,11 +2574,17 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - if (((grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_TYPE_OFFSET), dnode_path->dn.endian) >> 12) & 0xf) == 0xa) + if (((grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + + hdrsize + + SA_TYPE_OFFSET), + dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET; grub_size_t sym_sz = - grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), dnode_path->dn.endian); + grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + + hdrsize + + SA_SIZE_OFFSET), + dnode_path->dn.endian); char *oldpath = path, *oldpathbuf = path_buf; path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); if (!path_buf) @@ -3009,22 +3037,22 @@ nvlist_find_value (const char *nvlist, const char *name, * Loop thru the nvpair list * The XDR representation of an integer is in big-endian byte order. */ - while ((encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvlist))) + while ((encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (nvlist)))) { int nelm; nvpair = nvlist + 4 * 2; /* skip the encode/decode size */ - name_len = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair)); nvpair += 4; nvp_name = nvpair; nvpair = nvpair + ((name_len + 3) & ~3); /* align */ - type = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + type = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair)); nvpair += 4; - nelm = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + nelm = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair)); if (nelm < 1) return grub_error (GRUB_ERR_BAD_FS, "empty nvpair"); @@ -3061,7 +3089,7 @@ grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, return 0; } - *out = grub_be_to_cpu64 (*(grub_uint64_t *) nvpair); + *out = grub_be_to_cpu64 (grub_get_unaligned64 (nvpair)); return 1; } @@ -3082,7 +3110,7 @@ grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name) grub_error (GRUB_ERR_BAD_FS, "invalid string"); return 0; } - slen = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + slen = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair)); if (slen > size - 4) slen = size - 4; ret = grub_malloc (slen + 1); @@ -3138,7 +3166,7 @@ get_nvlist_size (const char *beg, const char *limit) ptr = beg + 8; while (ptr < limit - && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) ptr))) + && (encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (ptr)))) ptr += encode_size; /* goto the next nvpair */ ptr += 8; return (ptr > limit) ? -1 : (ptr - beg); @@ -3453,7 +3481,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) } hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - file->size = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); + file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); } else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) { @@ -3645,7 +3673,7 @@ fill_fs_info (struct grub_dirhook_info *info, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info->mtimeset = 1; - info->mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); } if (dn.dn.dn_bonustype == DMU_OT_ZNODE) @@ -3706,7 +3734,7 @@ grub_zfs_dir (grub_device_t device, const char *path, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info.mtimeset = 1; - info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); info.case_insensitive = data->subvol.case_insensitive; } diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 5adfdc290..f2b7cb1da 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -69,7 +69,8 @@ typedef struct zap_leaf_phys { * with the ZAP_LEAF_CHUNK() macro. */ - grub_uint16_t l_hash[1]; + grub_uint16_t l_hash[0]; + grub_properly_aligned_t l_entries[0]; } zap_leaf_phys_t; typedef union zap_leaf_chunk { diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 8b645c063..b1c46da3a 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -30,7 +30,7 @@ typedef struct zio_eck { grub_uint64_t zec_magic; /* for validation, endianness */ zio_cksum_t zec_cksum; /* 256-bit checksum */ -} zio_eck_t; +} __attribute__ ((packed)) zio_eck_t; /* * Gang block headers are self-checksumming and contain an array From b3950b849fc109954f8bd3671e41118f7ebd6ba2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 11:46:29 +0100 Subject: [PATCH 267/315] * grub-core/kern/mips/qemu_mips/init.c (grub_at_keyboard_init): Remove redundant declaration. (grub_serial_init): Likewise. (grub_terminfo_init): Likewise. --- ChangeLog | 7 +++++++ grub-core/kern/mips/qemu_mips/init.c | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa3c04c63..13b49c0b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/kern/mips/qemu_mips/init.c (grub_at_keyboard_init): Remove + redundant declaration. + (grub_serial_init): Likewise. + (grub_terminfo_init): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index d331e1b24..120b450f5 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -18,9 +18,6 @@ extern void grub_video_init (void); extern void grub_bitmap_init (void); extern void grub_font_init (void); extern void grub_gfxterm_init (void); -extern void grub_at_keyboard_init (void); -extern void grub_serial_init (void); -extern void grub_terminfo_init (void); extern void grub_keylayouts_init (void); extern void grub_boot_init (void); extern void grub_vga_text_init (void); From 9b05cad7686b9b490f7063640aec1eae120736c0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 13:58:33 +0100 Subject: [PATCH 268/315] * grub-core/fs/udf.c (grub_udf_partmap): Add packed attribute as it's not necessarily aligned. --- ChangeLog | 5 +++++ grub-core/fs/udf.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 13b49c0b3..159c14964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/udf.c (grub_udf_partmap): Add packed attribute + as it's not necessarily aligned. + 2011-12-13 Vladimir Serbinenko * grub-core/kern/mips/qemu_mips/init.c (grub_at_keyboard_init): Remove diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 4097fd2e6..537bb37f0 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -317,7 +317,7 @@ struct grub_udf_partmap grub_uint8_t ident[62]; } type2; }; -}; +} __attribute__ ((packed)); struct grub_udf_lvd { From 58acccd6457dfc71931cc3bd56bdf9d9f9703d0c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:17:24 +0100 Subject: [PATCH 269/315] * grub-core/fs/ntfs.c (u16at): Make into inline function. Handle unaligned pointers. (u32at): Likewise. (u64at): Likewise. (fixup): Use byte access instead of v16at. (find_attr): Fix imporper usage of v32at. (read_data): Likewise. (list_file): Handle byte-swapping and unaligned strings. (grub_ntfs_label): Likewise. --- ChangeLog | 12 +++++++++ grub-core/fs/ntfs.c | 62 +++++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 159c14964..f974c76bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (u16at): Make into inline function. + Handle unaligned pointers. + (u32at): Likewise. + (u64at): Likewise. + (fixup): Use byte access instead of v16at. + (find_attr): Fix imporper usage of v32at. + (read_data): Likewise. + (list_file): Handle byte-swapping and unaligned strings. + (grub_ntfs_label): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/udf.c (grub_udf_partmap): Add packed attribute diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index a432adce3..7dbe0e5e5 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -34,15 +34,23 @@ static grub_dl_t my_mod; #define grub_fshelp_node grub_ntfs_file -#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) +static inline grub_uint16_t +u16at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu16 (grub_get_unaligned16 ((char *) ptr + ofs)); +} -#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) -#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) -#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) +static inline grub_uint32_t +u32at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu32 (grub_get_unaligned32 ((char *) ptr + ofs)); +} -#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) -#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) -#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) +static inline grub_uint64_t +u64at (void *ptr, grub_size_t ofs) +{ + return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs)); +} grub_ntfscomp_func_t grub_ntfscomp_func; @@ -70,7 +78,8 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, const char *magic) pu += 2; if (u16at (buf, 0) != us) return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match"); - v16at (buf, 0) = v16at (pu, 0); + buf[0] = pu[0]; + buf[1] = pu[1]; ss--; } @@ -131,11 +140,11 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) if (at->flags & GRUB_NTFS_AF_MMFT) { if ((grub_disk_read - (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0, + (at->mft->data->disk, u32at (at->attr_cur, 0x10), 0, 512, at->emft_buf)) || (grub_disk_read - (at->mft->data->disk, v32at (at->attr_cur, 0x14), 0, + (at->mft->data->disk, u32at (at->attr_cur, 0x14), 0, 512, at->emft_buf + 512))) return NULL; @@ -228,8 +237,11 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) at->flags |= GRUB_NTFS_AF_GPOS; at->attr_cur = at->attr_nxt; pa = at->attr_cur; - v32at (pa, 0x10) = at->mft->data->mft_start; - v32at (pa, 0x14) = at->mft->data->mft_start + 1; + grub_set_unaligned32 ((char *) pa + 0x10, + grub_cpu_to_le32 (at->mft->data->mft_start)); + grub_set_unaligned32 ((char *) pa + 0x14, + grub_cpu_to_le32 (at->mft->data->mft_start + + 1)); pa = at->attr_nxt + u16at (pa, 4); while (pa < at->attr_end) { @@ -459,8 +471,8 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return grub_errno; st1 = ctx->curr_lcn * ctx->comp.spc; } - v32at (dest, 0) = st0; - v32at (dest, 4) = st1; + grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0)); + grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1)); return 0; } @@ -636,12 +648,18 @@ list_file (struct grub_ntfs_file *diro, char *pos, else fdiro->mtime = u64at (pos, 0x28); - ustr = grub_malloc (ns * 4 + 1); + ustr = grub_malloc (ns * GRUB_MAX_UTF8_PER_UTF16 + 1); if (ustr == NULL) return 0; - *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np, - ns) = '\0'; + { + grub_uint16_t tmp[ns]; + int i; + for (i = 0; i < ns; i++) + tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 ((char *) np + + 2 * i)); + *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, tmp, ns) = '\0'; + } if (namespace) type |= GRUB_FSHELP_CASE_INSENSITIVE; @@ -1163,8 +1181,14 @@ grub_ntfs_label (grub_device_t device, char **label) len = u32at (pa, 0x10) / 2; buf = grub_malloc (len * 4 + 1); pa += u16at (pa, 0x14); - *grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) = - '\0'; + { + grub_uint16_t tmp[len]; + int i; + for (i = 0; i < len; i++) + tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (pa + 2 * i)); + *grub_utf16_to_utf8 ((grub_uint8_t *) buf, tmp, len) = + '\0'; + } *label = buf; } From a23f2cc4d6838c64e54b6c5ea69c9da7731fcbe9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:40:41 +0100 Subject: [PATCH 270/315] * grub-core/partmap/sun.c (grub_sun_is_valid): make argument uint16_t * to ensure alignment. (sun_partition_map_iterate): Make `block' a union to ensure alignment. --- ChangeLog | 6 ++++++ grub-core/partmap/sun.c | 26 +++++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index f974c76bc..d5d98c193 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/partmap/sun.c (grub_sun_is_valid): make argument uint16_t * + to ensure alignment. + (sun_partition_map_iterate): Make `block' a union to ensure alignment. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/ntfs.c (u16at): Make into inline function. diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c index c7ef681c4..dfe51f35d 100644 --- a/grub-core/partmap/sun.c +++ b/grub-core/partmap/sun.c @@ -71,13 +71,13 @@ static struct grub_partition_map grub_sun_partition_map; /* Verify checksum (true=ok). */ static int -grub_sun_is_valid (struct grub_sun_block *label) +grub_sun_is_valid (grub_uint16_t *label) { grub_uint16_t *pos; grub_uint16_t sum = 0; - for (pos = (grub_uint16_t *) label; - pos < (grub_uint16_t *) (label + 1); + for (pos = label; + pos < (label + sizeof (struct grub_sun_block) / 2); pos++) sum ^= *pos; @@ -90,7 +90,11 @@ sun_partition_map_iterate (grub_disk_t disk, const grub_partition_t partition)) { struct grub_partition p; - struct grub_sun_block block; + union + { + struct grub_sun_block sun; + grub_uint16_t raw[0]; + } block; int partnum; grub_err_t err; @@ -100,10 +104,10 @@ sun_partition_map_iterate (grub_disk_t disk, if (err) return err; - if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic)) + if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.sun.magic)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table"); - if (! grub_sun_is_valid (&block)) + if (! grub_sun_is_valid (block.raw)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); /* Maybe another error value would be better, because partition @@ -112,14 +116,14 @@ sun_partition_map_iterate (grub_disk_t disk, { struct grub_sun_partition_descriptor *desc; - if (block.infos[partnum].id == 0 - || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID) + if (block.sun.infos[partnum].id == 0 + || block.sun.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID) continue; - desc = &block.partitions[partnum]; + desc = &block.sun.partitions[partnum]; p.start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder) - * grub_be_to_cpu16 (block.ntrks) - * grub_be_to_cpu16 (block.nsect)); + * grub_be_to_cpu16 (block.sun.ntrks) + * grub_be_to_cpu16 (block.sun.nsect)); p.len = grub_be_to_cpu32 (desc->num_sectors); p.number = p.index = partnum; if (p.len) From 93018f6400a1dd97ae93bc7bfb50c5c844322929 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:42:41 +0100 Subject: [PATCH 271/315] * grub-core/partmap/sunpc.c (grub_sun_is_valid): Make argument uint16_t * to ensure alignment. (sun_pc_partition_map_iterate): Make `block' a union to ensure alignment. --- ChangeLog | 9 ++++++++- grub-core/partmap/sunpc.c | 23 ++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5d98c193..c1ac0c00a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,13 @@ 2011-12-13 Vladimir Serbinenko - * grub-core/partmap/sun.c (grub_sun_is_valid): make argument uint16_t * + * grub-core/partmap/sunpc.c (grub_sun_is_valid): Make argument + uint16_t * to ensure alignment. + (sun_pc_partition_map_iterate): Make `block' a union to ensure + alignment. + +2011-12-13 Vladimir Serbinenko + + * grub-core/partmap/sun.c (grub_sun_is_valid): Make argument uint16_t * to ensure alignment. (sun_partition_map_iterate): Make `block' a union to ensure alignment. diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c index 28dc4f5be..1c1fdced0 100644 --- a/grub-core/partmap/sunpc.c +++ b/grub-core/partmap/sunpc.c @@ -53,13 +53,13 @@ static struct grub_partition_map grub_sun_pc_partition_map; /* Verify checksum (true=ok). */ static int -grub_sun_is_valid (struct grub_sun_pc_block *label) +grub_sun_is_valid (grub_uint16_t *label) { grub_uint16_t *pos; grub_uint16_t sum = 0; - for (pos = (grub_uint16_t *) label; - pos < (grub_uint16_t *) (label + 1); + for (pos = label; + pos < (label + sizeof (struct grub_sun_pc_block) / 2); pos++) sum ^= *pos; @@ -72,7 +72,11 @@ sun_pc_partition_map_iterate (grub_disk_t disk, const grub_partition_t partition)) { grub_partition_t p; - struct grub_sun_pc_block block; + union + { + struct grub_sun_pc_block sun; + grub_uint16_t raw[0]; + } block; int partnum; grub_err_t err; @@ -88,14 +92,14 @@ sun_pc_partition_map_iterate (grub_disk_t disk, return err; } - if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.magic)) + if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.sun.magic)) { grub_free (p); return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun_pc partition table"); } - if (! grub_sun_is_valid (&block)) + if (! grub_sun_is_valid (block.raw)) { grub_free (p); return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); @@ -107,11 +111,12 @@ sun_pc_partition_map_iterate (grub_disk_t disk, { struct grub_sun_pc_partition_descriptor *desc; - if (block.partitions[partnum].id == 0 - || block.partitions[partnum].id == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID) + if (block.sun.partitions[partnum].id == 0 + || block.sun.partitions[partnum].id + == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID) continue; - desc = &block.partitions[partnum]; + desc = &block.sun.partitions[partnum]; p->start = grub_le_to_cpu32 (desc->start_sector); p->len = grub_le_to_cpu32 (desc->num_sectors); p->number = partnum; From 85c85365bbc3d6178c20c1fdd4bfe832b883ab7d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:44:38 +0100 Subject: [PATCH 272/315] * grub-core/partmap/dvh.c (grub_dvh_is_valid): Make argument uint32_t * to ensure alignment. (dvh_partition_map_iterate): Make `block' a union to ensure alignment. --- ChangeLog | 6 ++++++ grub-core/partmap/dvh.c | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1ac0c00a..5d4a34fe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/partmap/dvh.c (grub_dvh_is_valid): Make argument + uint32_t * to ensure alignment. + (dvh_partition_map_iterate): Make `block' a union to ensure alignment. + 2011-12-13 Vladimir Serbinenko * grub-core/partmap/sunpc.c (grub_sun_is_valid): Make argument diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c index 118401612..c8f467eb5 100644 --- a/grub-core/partmap/dvh.c +++ b/grub-core/partmap/dvh.c @@ -49,13 +49,13 @@ static struct grub_partition_map grub_dvh_partition_map; /* Verify checksum (true=ok). */ static int -grub_dvh_is_valid (struct grub_dvh_block *label) +grub_dvh_is_valid (grub_uint32_t *label) { grub_uint32_t *pos; grub_uint32_t sum = 0; - for (pos = (grub_uint32_t *) label; - pos < (grub_uint32_t *) (label + 1); + for (pos = label; + pos < (label + sizeof (struct grub_dvh_block) / 4); pos++) sum += *pos; @@ -68,7 +68,11 @@ dvh_partition_map_iterate (grub_disk_t disk, const grub_partition_t partition)) { struct grub_partition p; - struct grub_dvh_block block; + union + { + struct grub_dvh_block dvh; + grub_uint32_t raw[0]; + } block; unsigned partnum; grub_err_t err; @@ -78,24 +82,24 @@ dvh_partition_map_iterate (grub_disk_t disk, if (err) return err; - if (DVH_MAGIC != grub_be_to_cpu32 (block.magic)) + if (DVH_MAGIC != grub_be_to_cpu32 (block.dvh.magic)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table"); - if (! grub_dvh_is_valid (&block)) + if (! grub_dvh_is_valid (block.raw)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); /* Maybe another error value would be better, because partition table _is_ recognized but invalid. */ - for (partnum = 0; partnum < ARRAY_SIZE (block.parts); partnum++) + for (partnum = 0; partnum < ARRAY_SIZE (block.dvh.parts); partnum++) { - if (block.parts[partnum].length == 0) + if (block.dvh.parts[partnum].length == 0) continue; if (partnum == 10) continue; - p.start = grub_be_to_cpu32 (block.parts[partnum].start); - p.len = grub_be_to_cpu32 (block.parts[partnum].length); + p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start); + p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length); p.number = p.index = partnum; if (hook (disk, &p)) break; From 753ef8c113267b08ffaf568ac70016c82f35ce96 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:47:00 +0100 Subject: [PATCH 273/315] * include/grub/efi/memory.h (grub_machine_mmap_iterate): Remove redundant declaration. (grub_mmap_get_post64): Likewise. (grub_mmap_get_upper): Likewise. (grub_mmap_get_lower): Likewise. --- ChangeLog | 8 ++++++++ include/grub/efi/memory.h | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5d4a34fe8..f6b3d5ef0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/efi/memory.h (grub_machine_mmap_iterate): + Remove redundant declaration. + (grub_mmap_get_post64): Likewise. + (grub_mmap_get_upper): Likewise. + (grub_mmap_get_lower): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/partmap/dvh.c (grub_dvh_is_valid): Make argument diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h index 133f9504c..20526b146 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -24,15 +24,8 @@ #define GRUB_MMAP_REGISTER_BY_FIRMWARE 1 -grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)); grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size, int type, int handle); grub_err_t grub_machine_mmap_unregister (int handle); -grub_uint64_t grub_mmap_get_post64 (void); -grub_uint64_t grub_mmap_get_upper (void); -grub_uint64_t grub_mmap_get_lower (void); - #endif /* ! GRUB_MEMORY_MACHINE_HEADER */ From 0d51ee20eee82711c859175d7b459cd4b46f6082 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:51:41 +0100 Subject: [PATCH 274/315] * include/grub/emu/misc.h (xasprintf): Add missing format attribute. * include/grub/mips/kernel.h (grub_halt): Remove redundant declaration. * include/grub/mips/qemu_mips/kernel.h (grub_halt): Likewise. * include/grub/misc.h (grub_reboot) [GRUB_MACHINE_EMU || GRUB_MACHINE_QEMU_MIPS]: Export. (grub_halt) [__mips__]: Likewise. --- ChangeLog | 9 +++++++++ include/grub/emu/misc.h | 5 +---- include/grub/mips/kernel.h | 6 ------ include/grub/mips/qemu_mips/kernel.h | 1 - include/grub/misc.h | 6 ++++++ 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6b3d5ef0..293b11150 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/emu/misc.h (xasprintf): Add missing format attribute. + * include/grub/mips/kernel.h (grub_halt): Remove redundant declaration. + * include/grub/mips/qemu_mips/kernel.h (grub_halt): Likewise. + * include/grub/misc.h (grub_reboot) + [GRUB_MACHINE_EMU || GRUB_MACHINE_QEMU_MIPS]: Export. + (grub_halt) [__mips__]: Likewise. + 2011-12-13 Vladimir Serbinenko * include/grub/efi/memory.h (grub_machine_mmap_iterate): diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index b4b8f7d28..a9365f6a1 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -60,7 +60,7 @@ grub_util_device_is_mapped (const char *dev); void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result)); void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result)); char * EXPORT_FUNC(xstrdup) (const char *str) __attribute__ ((warn_unused_result)); -char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((warn_unused_result)); +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))) __attribute__ ((warn_unused_result)); void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); @@ -82,7 +82,4 @@ int grub_device_mapper_supported (void); char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot); -void EXPORT_FUNC(grub_reboot) (void); - - #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index d351f17cb..07b08848d 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -21,10 +21,4 @@ #include -#ifndef ASM_FILE - -void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); - -#endif - #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/qemu_mips/kernel.h b/include/grub/mips/qemu_mips/kernel.h index 1e7e32401..8b8b0149e 100644 --- a/include/grub/mips/qemu_mips/kernel.h +++ b/include/grub/mips/qemu_mips/kernel.h @@ -23,7 +23,6 @@ #ifndef ASM_FILE -void EXPORT_FUNC (grub_halt) (void); void grub_qemu_init_cirrus (void); #endif diff --git a/include/grub/misc.h b/include/grub/misc.h index 0344d528b..46715f77c 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -405,12 +405,18 @@ grub_div_roundup (unsigned int x, unsigned int y) } /* Reboot the machine. */ +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) +void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); +#else void grub_reboot (void) __attribute__ ((noreturn)); +#endif #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't * use APM even if it is available. */ void grub_halt (int no_apm) __attribute__ ((noreturn)); +#elif defined (__mips__) +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); #else void grub_halt (void) __attribute__ ((noreturn)); #endif From 6166442083b9d7febca0e03300481f528fe79d51 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 14:57:46 +0100 Subject: [PATCH 275/315] * grub-core/commands/hdparm.c (le16_to_char): Make src and dest uint16 * to ensure alignment. (grub_hdparm_print_identify): Make argument uint16 * to ensure alignment. Ensure tmp alignment. (grub_cmd_hdparm): Ensure buf alignment. * grub-core/disk/ata.c (grub_ata_strncpy): Make src and dest uint16 * to ensure alignment. (grub_ata_dumpinfo): Ensure text alignment. (grub_atapi_identify): Preserve alignment invariant. (grub_ata_identify): Likewise. Use grub_get_unaligned32 when necessary. --- ChangeLog | 13 ++++++++++ grub-core/commands/hdparm.c | 18 +++++++------- grub-core/disk/ata.c | 48 ++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 293b11150..55230a081 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/commands/hdparm.c (le16_to_char): Make src and dest uint16 * + to ensure alignment. + (grub_hdparm_print_identify): Make argument uint16 * to ensure + alignment. Ensure tmp alignment. + (grub_cmd_hdparm): Ensure buf alignment. + * grub-core/disk/ata.c (grub_ata_strncpy): Make src and dest uint16 * + to ensure alignment. + (grub_ata_dumpinfo): Ensure text alignment. + (grub_atapi_identify): Preserve alignment invariant. + (grub_ata_identify): Likewise. Use grub_get_unaligned32 when necessary. + 2011-12-13 Vladimir Serbinenko * include/grub/emu/misc.h (xasprintf): Add missing format attribute. diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index 240170734..85189e8bc 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -165,22 +165,20 @@ grub_hdparm_set_val_cmd (const char * msg, int val, } static const char * -le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes) +le16_to_char (grub_uint16_t *dest, const grub_uint16_t * src16, unsigned bytes) { - grub_uint16_t * dest16 = (grub_uint16_t *) dest; unsigned i; for (i = 0; i < bytes / 2; i++) - dest16[i] = grub_be_to_cpu16 (src16[i]); - return dest; + dest[i] = grub_be_to_cpu16 (src16[i]); + dest[i] = 0; + return (char *) dest; } static void -grub_hdparm_print_identify (const char * idbuf) +grub_hdparm_print_identify (const grub_uint16_t * idw) { - const grub_uint16_t * idw = (const grub_uint16_t *) idbuf; - /* Print identity strings. */ - char tmp[40]; + grub_uint16_t tmp[21]; grub_printf ("Model: \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40)); grub_printf ("Firmware: \"%.8s\"\n", le16_to_char (tmp, &idw[23], 8)); grub_printf ("Serial: \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20)); @@ -377,7 +375,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state???? /* Print/dump IDENTIFY. */ if (ident || dumpid) { - char buf[GRUB_DISK_SECTOR_SIZE]; + grub_uint16_t buf[GRUB_DISK_SECTOR_SIZE / 2]; if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE, 0, 0, buf, sizeof (buf))) grub_printf ("Cannot read ATA IDENTIFY data\n"); @@ -386,7 +384,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state???? if (ident) grub_hdparm_print_identify (buf); if (dumpid) - hexdump (0, buf, sizeof (buf)); + hexdump (0, (char *) buf, sizeof (buf)); } } diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 330635f57..50559a815 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -29,29 +29,27 @@ static grub_ata_dev_t grub_ata_dev_list; /* Byteorder has to be changed before strings can be read. */ static void -grub_ata_strncpy (char *dst, char *src, grub_size_t len) +grub_ata_strncpy (grub_uint16_t *dst16, grub_uint16_t *src16, grub_size_t len) { - grub_uint16_t *src16 = (grub_uint16_t *) src; - grub_uint16_t *dst16 = (grub_uint16_t *) dst; unsigned int i; for (i = 0; i < len / 2; i++) *(dst16++) = grub_be_to_cpu16 (*(src16++)); - dst[len] = '\0'; + dst16[i] = 0; } static void -grub_ata_dumpinfo (struct grub_ata *dev, char *info) +grub_ata_dumpinfo (struct grub_ata *dev, grub_uint16_t *info) { - char text[41]; + grub_uint16_t text[21]; /* The device information was read, dump it for debugging. */ - grub_ata_strncpy (text, info + 20, 20); - grub_dprintf ("ata", "Serial: %s\n", text); - grub_ata_strncpy (text, info + 46, 8); - grub_dprintf ("ata", "Firmware: %s\n", text); - grub_ata_strncpy (text, info + 54, 40); - grub_dprintf ("ata", "Model: %s\n", text); + grub_ata_strncpy (text, info + 10, 20); + grub_dprintf ("ata", "Serial: %s\n", (char *) text); + grub_ata_strncpy (text, info + 23, 8); + grub_dprintf ("ata", "Firmware: %s\n", (char *) text); + grub_ata_strncpy (text, info + 27, 40); + grub_dprintf ("ata", "Model: %s\n", (char *) text); if (! dev->atapi) { @@ -65,7 +63,7 @@ static grub_err_t grub_atapi_identify (struct grub_ata *dev) { struct grub_disk_ata_pass_through_parms parms; - char *info; + grub_uint16_t *info; grub_err_t err; info = grub_malloc (GRUB_DISK_SECTOR_SIZE); @@ -105,17 +103,19 @@ static grub_err_t grub_ata_identify (struct grub_ata *dev) { struct grub_disk_ata_pass_through_parms parms; - char *info; + grub_uint64_t *info64; + grub_uint32_t *info32; grub_uint16_t *info16; grub_err_t err; - info = grub_malloc (GRUB_DISK_SECTOR_SIZE); - if (! info) + info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE); + info32 = (grub_uint32_t *) info64; + info16 = (grub_uint16_t *) info64; + if (! info16) return grub_errno; - info16 = (grub_uint16_t *) info; grub_memset (&parms, 0, sizeof (parms)); - parms.buffer = info; + parms.buffer = info16; parms.size = GRUB_DISK_SECTOR_SIZE; parms.taskfile.disk = 0xE0; @@ -126,7 +126,7 @@ grub_ata_identify (struct grub_ata *dev) if (err || parms.size != GRUB_DISK_SECTOR_SIZE) { grub_uint8_t sts = parms.taskfile.status; - grub_free (info); + grub_free (info16); grub_errno = GRUB_ERR_NONE; if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR @@ -167,14 +167,14 @@ grub_ata_identify (struct grub_ata *dev) /* Determine the amount of sectors. */ if (dev->addr != GRUB_ATA_LBA48) - dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60])); + dev->size = grub_le_to_cpu32 (info32[30]); else - dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); + dev->size = grub_le_to_cpu64 (info64[25]); if (info16[106] & (1 << 12)) { grub_uint32_t secsize; - secsize = grub_le_to_cpu32 (*((grub_uint32_t *) &info16[117])); + secsize = grub_le_to_cpu32 (grub_get_unaligned32 (&info16[117])); if (secsize & (secsize - 1) || !secsize || secsize > 1048576) secsize = 256; @@ -191,9 +191,9 @@ grub_ata_identify (struct grub_ata *dev) dev->heads = info16[3]; dev->sectors_per_track = info16[6]; - grub_ata_dumpinfo (dev, info); + grub_ata_dumpinfo (dev, info16); - grub_free(info); + grub_free (info16); return 0; } From d1c501ee949d64bea8fa54ab52a1ce044317c86d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 15:03:06 +0100 Subject: [PATCH 276/315] * include/grub/net.h (grub_net_network_level_interfaces): Remove redundant declaration. (FOR_NET_NETWORK_LEVEL_INTERFACES): Move to appropriate place. --- ChangeLog | 6 ++++++ include/grub/net.h | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 55230a081..74bc77345 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/net.h (grub_net_network_level_interfaces): Remove + redundant declaration. + (FOR_NET_NETWORK_LEVEL_INTERFACES): Move to appropriate place. + 2011-12-13 Vladimir Serbinenko * grub-core/commands/hdparm.c (le16_to_char): Make src and dest uint16 * diff --git a/include/grub/net.h b/include/grub/net.h index 03af637b5..2ec89e191 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -302,6 +302,7 @@ grub_net_add_addr (const char *name, grub_net_interface_flags_t flags); extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) extern grub_net_app_level_t grub_net_app_level_list; @@ -423,9 +424,6 @@ void grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf); -extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) - #define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = var->next; var; var = next, next = var->next) void From 2019d09ef08866e4f26adaac8659ca6dc5fab321 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 15:04:07 +0100 Subject: [PATCH 277/315] * include/grub/i386/qemu/memory.h (grub_machine_mmap_init): Remove redundant declaration. --- ChangeLog | 5 +++++ include/grub/i386/qemu/memory.h | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74bc77345..a2a8609ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/i386/qemu/memory.h (grub_machine_mmap_init): Remove + redundant declaration. + 2011-12-13 Vladimir Serbinenko * include/grub/net.h (grub_net_network_level_interfaces): Remove diff --git a/include/grub/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h index 2003e4934..f152cd782 100644 --- a/include/grub/i386/qemu/memory.h +++ b/include/grub/i386/qemu/memory.h @@ -33,10 +33,4 @@ #define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ #define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START -#ifndef ASM_FILE - -void grub_machine_mmap_init (void); - -#endif - #endif /* ! _GRUB_MEMORY_MACHINE_HEADER */ From 02a2bf83840959729f45895bae5452654f9cfbc5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 15:13:51 +0100 Subject: [PATCH 278/315] Add noreturn attributes and remove unreachable code. * grub-core/bus/cs5536.c (grub_cs5536_smbus_wait): Remove unreachable code. * grub-core/commands/halt.c (grub_cmd_halt): Remove unreachable code. Mark as noreturn. * grub-core/commands/minicmd.c (grub_mini_cmd_exit): Likewise. * grub-core/commands/reboot.c (grub_cmd_reboot): Likewise. * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Remove unreachable code. * grub-core/kern/main.c (grub_main): Mark as noreturn. * grub-core/kern/rescue_reader.c (grub_rescue_run): Likewise. * grub-core/lib/posix_wrap/stdlib.h (abort): Likewise. * grub-core/normal/menu.c (run_menu): Remove unreachable code. * include/grub/kernel.h (grub_main): Mark as noreturn. * include/grub/reader.h (grub_rescue_run): Likewise. --- ChangeLog | 19 +++++++++++++++++++ grub-core/bus/cs5536.c | 2 -- grub-core/commands/halt.c | 3 +-- grub-core/commands/minicmd.c | 4 ++-- grub-core/commands/reboot.c | 3 +-- grub-core/disk/efi/efidisk.c | 2 -- grub-core/kern/main.c | 2 +- grub-core/kern/rescue_reader.c | 2 +- grub-core/lib/posix_wrap/stdlib.h | 2 +- grub-core/normal/menu.c | 1 - include/grub/kernel.h | 2 +- include/grub/reader.h | 2 +- 12 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2a8609ab..f62cc0ba6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-12-13 Vladimir Serbinenko + + Add noreturn attributes and remove unreachable code. + + * grub-core/bus/cs5536.c (grub_cs5536_smbus_wait): Remove unreachable + code. + * grub-core/commands/halt.c (grub_cmd_halt): Remove unreachable + code. Mark as noreturn. + * grub-core/commands/minicmd.c (grub_mini_cmd_exit): Likewise. + * grub-core/commands/reboot.c (grub_cmd_reboot): Likewise. + * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Remove + unreachable code. + * grub-core/kern/main.c (grub_main): Mark as noreturn. + * grub-core/kern/rescue_reader.c (grub_rescue_run): Likewise. + * grub-core/lib/posix_wrap/stdlib.h (abort): Likewise. + * grub-core/normal/menu.c (run_menu): Remove unreachable code. + * include/grub/kernel.h (grub_main): Mark as noreturn. + * include/grub/reader.h (grub_rescue_run): Likewise. + 2011-12-13 Vladimir Serbinenko * include/grub/i386/qemu/memory.h (grub_machine_mmap_init): Remove diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 1aae7852e..9e7796ea1 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -97,8 +97,6 @@ grub_cs5536_smbus_wait (grub_port_t smbbase) if (grub_get_time_ms () > start + 40) return grub_error (GRUB_ERR_IO, "SM stalled"); } - - return GRUB_ERR_NONE; } grub_err_t diff --git a/grub-core/commands/halt.c b/grub-core/commands/halt.c index 317f7753f..f8596ecdc 100644 --- a/grub-core/commands/halt.c +++ b/grub-core/commands/halt.c @@ -24,13 +24,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t +static grub_err_t __attribute__ ((noreturn)) grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { grub_halt (); - return 0; } static grub_command_t cmd; diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index 1bb0147df..f436cd55d 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -165,13 +165,13 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), } /* exit */ -static grub_err_t +static grub_err_t __attribute__ ((noreturn)) grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { grub_exit (); - return 0; + /* Not reached. */ } static grub_command_t cmd_cat, cmd_help; diff --git a/grub-core/commands/reboot.c b/grub-core/commands/reboot.c index 8e18083c0..46d364c99 100644 --- a/grub-core/commands/reboot.c +++ b/grub-core/commands/reboot.c @@ -24,13 +24,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t +static grub_err_t __attribute__ ((noreturn)) grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { grub_reboot (); - return 0; } static grub_command_t cmd; diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 0baeb8e4b..bbb8c93b1 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -791,6 +791,4 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) grub_disk_close (parent); return device_name; } - - return 0; } diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index bf2789860..185230c5c 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -190,7 +190,7 @@ grub_load_normal_mode (void) } /* The main routine. */ -void +void __attribute__ ((noreturn)) grub_main (void) { /* First of all, initialize the machine. */ diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c index a81008579..4587b944f 100644 --- a/grub-core/kern/rescue_reader.c +++ b/grub-core/kern/rescue_reader.c @@ -74,7 +74,7 @@ grub_rescue_read_line (char **line, int cont) return 0; } -void +void __attribute__ ((noreturn)) grub_rescue_run (void) { grub_printf ("Entering rescue mode...\n"); diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h index 4c725f6e2..b35e21bb8 100644 --- a/grub-core/lib/posix_wrap/stdlib.h +++ b/grub-core/lib/posix_wrap/stdlib.h @@ -46,7 +46,7 @@ realloc (void *ptr, grub_size_t size) return grub_realloc (ptr, size); } -static inline void +static inline void __attribute__ ((noreturn)) abort (void) { grub_abort (); diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index b75e9f523..ae8e3e681 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -666,7 +666,6 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } /* Never reach here. */ - return -1; } /* Callback invoked immediately before a menu entry is executed. */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index f9fc817db..f587de514 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -82,7 +82,7 @@ extern grub_addr_t EXPORT_VAR (grub_modbase); grub_addr_t grub_modules_get_end (void); /* The start point of the C code. */ -void grub_main (void); +void grub_main (void) __attribute__ ((noreturn)); /* The machine-specific initialization. This must initialize memory. */ void grub_machine_init (void); diff --git a/include/grub/reader.h b/include/grub/reader.h index fd72a3252..cd92df8f2 100644 --- a/include/grub/reader.h +++ b/include/grub/reader.h @@ -24,6 +24,6 @@ typedef grub_err_t (*grub_reader_getline_t) (char **, int); -void grub_rescue_run (void); +void grub_rescue_run (void) __attribute__ ((noreturn)); #endif /* ! GRUB_READER_HEADER */ From b70b6d11073ed0f10a04fb007c38cd896cea92b6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 15:55:36 +0100 Subject: [PATCH 279/315] * grub-core/disk/pata.c (grub_pata_pio_read): Handle unaligned buffer. (grub_pata_pio_write): Likewise. --- ChangeLog | 5 +++++ grub-core/disk/pata.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index f62cc0ba6..06572f7a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/disk/pata.c (grub_pata_pio_read): Handle unaligned buffer. + (grub_pata_pio_write): Likewise. + 2011-12-13 Vladimir Serbinenko Add noreturn attributes and remove unreachable code. diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index c54fe91ab..ff76cc1fb 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -116,12 +116,13 @@ grub_pata_wait (void) static void grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size) { - grub_uint16_t *buf16 = (grub_uint16_t *) buf; unsigned int i; /* Read in the data, word by word. */ for (i = 0; i < size / 2; i++) - buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA)); + grub_set_unaligned16 (buf + 2 * i, + grub_le_to_cpu16 (grub_inw(dev->ioaddress + + GRUB_ATA_REG_DATA))); if (size & 1) buf[size - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA)); @@ -130,12 +131,11 @@ grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size) static void grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size) { - grub_uint16_t *buf16 = (grub_uint16_t *) buf; unsigned int i; /* Write the data, word by word. */ for (i = 0; i < size / 2; i++) - grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA); + grub_outw(grub_cpu_to_le16 (grub_get_unaligned16 (buf + 2 * i)), dev->ioaddress + GRUB_ATA_REG_DATA); } /* ATA pass through support, used by hdparm.mod. */ From c2e777777b6c4d4c0d37fc2d005e7dc47d0a6077 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 16:20:25 +0100 Subject: [PATCH 280/315] * grub-core/loader/i386/xnu.c (grub_xnu_devprop_remove_property): Fix incorrect pointer. --- ChangeLog | 5 +++++ grub-core/loader/i386/xnu.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 06572f7a9..0ef874d70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/loader/i386/xnu.c (grub_xnu_devprop_remove_property): Fix + incorrect pointer. + 2011-12-13 Vladimir Serbinenko * grub-core/disk/pata.c (grub_pata_pio_read): Handle unaligned buffer. diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 1df8dc4c0..4d3678ea1 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -226,7 +226,7 @@ grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev char *name) { struct property_descriptor *prop; - prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name); + prop = grub_named_list_find (GRUB_AS_NAMED_LIST (dev->properties), name); if (!prop) return GRUB_ERR_NONE; From 0c6087a8c9d0b0ef4ad79829fe1ec58997f77166 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 16:22:44 +0100 Subject: [PATCH 281/315] * grub-core/loader/multiboot_mbi2.c (grub_multiboot_add_elfsyms): Reserve alignment invariants. (grub_multiboot_load): Likewise. (retrieve_video_parameters): Likewise. (grub_multiboot_make_mbi): Likewise. --- ChangeLog | 8 ++++ grub-core/loader/multiboot_mbi2.c | 78 ++++++++++++++++++++----------- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ef874d70..fd260b57e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/loader/multiboot_mbi2.c (grub_multiboot_add_elfsyms): + Reserve alignment invariants. + (grub_multiboot_load): Likewise. + (retrieve_video_parameters): Likewise. + (grub_multiboot_make_mbi): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/loader/i386/xnu.c (grub_xnu_devprop_remove_property): Fix diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 05f581bb6..9a81afe8e 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -78,7 +78,7 @@ grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, grub_err_t grub_multiboot_load (grub_file_t file) { - char *buffer; + grub_properly_aligned_t *buffer; grub_ssize_t len; struct multiboot_header *header; grub_err_t err; @@ -101,11 +101,13 @@ grub_multiboot_load (grub_file_t file) return grub_error (GRUB_ERR_BAD_OS, "file too small"); } + COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0); + /* Look for the multiboot header in the buffer. The header should be at least 12 bytes and aligned on a 4-byte boundary. */ for (header = (struct multiboot_header *) buffer; - ((char *) header <= buffer + len - 12) || (header = 0); - header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN)) + ((char *) header <= (char *) buffer + len - 12) || (header = 0); + header = (struct multiboot_header *) ((grub_uint32_t *) header + MULTIBOOT_HEADER_ALIGN / 4)) { if (header->magic == MULTIBOOT_HEADER_MAGIC && !(header->magic + header->architecture @@ -120,9 +122,11 @@ grub_multiboot_load (grub_file_t file) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); } + COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % 4 == 0); + for (tag = (struct multiboot_header_tag *) (header + 1); tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_header_tag *) ((char *) tag + tag->size)) + tag = (struct multiboot_header_tag *) ((grub_uint32_t *) tag + ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) / 4)) switch (tag->type) { case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST: @@ -208,7 +212,7 @@ grub_multiboot_load (grub_file_t file) if (addr_tag) { - int offset = ((char *) header - buffer - + int offset = ((char *) header - (char *) buffer - (addr_tag->header_addr - addr_tag->load_addr)); int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset : addr_tag->load_end_addr - addr_tag->load_addr); @@ -415,7 +419,7 @@ fill_vbe_tag (struct multiboot_tag_vbe *tag) #endif static grub_err_t -retrieve_video_parameters (grub_uint8_t **ptrorig) +retrieve_video_parameters (grub_properly_aligned_t **ptrorig) { grub_err_t err; struct grub_video_mode_info mode_info; @@ -493,7 +497,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; tag->common.size = sizeof (tag->common); tag->common.reserved = 0; - *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN); + *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } return GRUB_ERR_NONE; } @@ -508,7 +513,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) fill_vbe_tag (tag_vbe); - *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN); + *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } #endif @@ -559,7 +565,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6; } - *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN); + *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); return GRUB_ERR_NONE; } @@ -567,14 +574,16 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) grub_err_t grub_multiboot_make_mbi (grub_uint32_t *target) { - grub_uint8_t *ptrorig; - grub_uint8_t *mbistart; + grub_properly_aligned_t *ptrorig; + grub_properly_aligned_t *mbistart; grub_err_t err; grub_size_t bufsize; grub_relocator_chunk_t ch; bufsize = grub_multiboot_get_mbi_size (); + COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); + err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0, 0xffffffff - bufsize, bufsize, MULTIBOOT_TAG_ALIGN, @@ -592,14 +601,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target) #endif mbistart = ptrorig; - ptrorig += 2 * sizeof (grub_uint32_t); + COMPILE_TIME_ASSERT ((2 * sizeof (grub_uint32_t)) + % sizeof (grub_properly_aligned_t) == 0); + COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN + % sizeof (grub_properly_aligned_t) == 0); + ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t); { struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_CMDLINE; tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; grub_memcpy (tag->string, cmdline, cmdline_size); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } { @@ -607,7 +621,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME; tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING)); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } #ifdef GRUB_MACHINE_PCBIOS @@ -630,7 +645,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->cseg_16_len = info.cseg_16_len; tag->version = info.version; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } } #endif @@ -648,14 +664,16 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->mod_start = cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } } { struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig; grub_fill_multiboot_mmap (tag); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } { @@ -668,7 +686,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->num = elf_sec_num; tag->entsize = elf_sec_entsize; tag->shndx = elf_sec_shstrndx; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } { @@ -680,7 +699,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) /* Convert from bytes to kilobytes. */ tag->mem_lower = grub_mmap_get_lower () / 1024; tag->mem_upper = grub_mmap_get_upper () / 1024; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } if (bootdev_set) @@ -693,7 +713,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->biosdev = biosdev; tag->slice = slice; tag->part = part; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } { @@ -711,7 +732,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->type = MULTIBOOT_TAG_TYPE_EFI64; tag->size = sizeof (*tag); tag->pointer = (grub_addr_t) grub_efi_system_table; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } #endif @@ -721,7 +743,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->type = MULTIBOOT_TAG_TYPE_EFI32; tag->size = sizeof (*tag); tag->pointer = (grub_addr_t) grub_efi_system_table; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } #endif @@ -735,7 +758,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD; tag->size = sizeof (*tag) + sizeof (*a); grub_memcpy (tag->rsdp, a, sizeof (*a)); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } } @@ -748,7 +772,8 @@ grub_multiboot_make_mbi (grub_uint32_t *target) tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW; tag->size = sizeof (*tag) + a->length; grub_memcpy (tag->rsdp, a, a->length); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } } #endif @@ -757,10 +782,11 @@ grub_multiboot_make_mbi (grub_uint32_t *target) struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_END; tag->size = sizeof (struct multiboot_tag); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) + / sizeof (grub_properly_aligned_t); } - ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart; + ((grub_uint32_t *) mbistart)[0] = (char *) ptrorig - (char *) mbistart; ((grub_uint32_t *) mbistart)[1] = 0; return GRUB_ERR_NONE; From 30dd48c2b02a8808d1c164010d3cf28c793681d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 16:29:15 +0100 Subject: [PATCH 282/315] * include/grub/kernel.h (FOR_MODULES): Preserve alignment invariants. --- ChangeLog | 4 ++++ include/grub/kernel.h | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd260b57e..574f63cb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * include/grub/kernel.h (FOR_MODULES): Preserve alignment invariants. + 2011-12-13 Vladimir Serbinenko * grub-core/loader/multiboot_mbi2.c (grub_multiboot_add_elfsyms): diff --git a/include/grub/kernel.h b/include/grub/kernel.h index f587de514..c9a549675 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -71,13 +71,15 @@ struct grub_module_info64 extern grub_addr_t EXPORT_VAR (grub_modbase); -#define FOR_MODULES(var) for (\ - var = grub_modbase ? (struct grub_module_header *) \ +#define FOR_MODULES(var) for (var = grub_modbase ? (struct grub_module_header *) \ (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ var && (grub_addr_t) var \ < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ var = (struct grub_module_header *) \ - ((char *) var + ((struct grub_module_header *) var)->size)) + ((grub_uint32_t *) var \ + + ((((struct grub_module_header *) var)->size \ + + sizeof (grub_uint32_t) - 1) \ + / sizeof (grub_uint32_t)))) grub_addr_t grub_modules_get_end (void); From dc71319397a1e24763bea5495e89f56237ce2185 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 16:33:27 +0100 Subject: [PATCH 283/315] * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Force inlining of add_part to workaround compiler bug. --- ChangeLog | 5 +++++ grub-core/fs/iso9660.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 574f63cb4..8f30b557a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Force inlining of + add_part to workaround compiler bug. + 2011-12-13 Vladimir Serbinenko * include/grub/kernel.h (FOR_MODULES): Preserve alignment invariants. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 7b1e32f7c..048c361a6 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -533,10 +533,12 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_off_t len; char *symlink = 0; - auto void add_part (const char *part, int len); - /* Extend the symlink. */ - void add_part (const char *part, int len2) + auto inline void __attribute__ ((always_inline)) add_part (const char *part, + int len2); + + auto inline void __attribute__ ((always_inline)) add_part (const char *part, + int len2) { int size = symlink ? grub_strlen (symlink) : 0; From 9b4baaa4ee24a54d354f64cf294dd4b9a35947bd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 16:35:12 +0100 Subject: [PATCH 284/315] * grub-core/fs/iso9660.c (grub_iso9660_convert_string): Make first argument a u8 pointer. All users updated. Handle unaligned buffers. --- ChangeLog | 6 ++++++ grub-core/fs/iso9660.c | 14 +++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f30b557a..833d80a8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_convert_string): Make first + argument a u8 pointer. All users updated. + Handle unaligned buffers. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Force inlining of diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 048c361a6..fb5da2aa7 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -331,19 +331,20 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, } static char * -grub_iso9660_convert_string (grub_uint16_t *us, int len) +grub_iso9660_convert_string (grub_uint8_t *us, int len) { char *p; int i; + grub_uint16_t t[len]; - p = grub_malloc (len * 4 + 1); + p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); if (! p) return p; for (i=0; i> 1); + ((grub_uint8_t *) oldname, dirent.namelen >> 1); semicolon = grub_strrchr (filename, ';'); if (semicolon) @@ -978,8 +979,7 @@ grub_iso9660_label (grub_device_t device, char **label) if (data) { if (data->joliet) - *label = grub_iso9660_convert_string - ((grub_uint16_t *) &data->voldesc.volname, 16); + *label = grub_iso9660_convert_string (data->voldesc.volname, 16); else *label = grub_strndup ((char *) data->voldesc.volname, 32); if (*label) From e59b7857f88e3aac8a9a8e516aa9bf2079000ceb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 19:53:57 +0100 Subject: [PATCH 285/315] * grub-core/commands/videotest.c (grub_cmd_videotest): Check that allocation succeeded. --- ChangeLog | 5 +++++ grub-core/commands/videotest.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 833d80a8a..7ea8d1001 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/commands/videotest.c (grub_cmd_videotest): Check that + allocation succeeded. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_convert_string): Make first diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c index dc7a6485f..11949a6fc 100644 --- a/grub-core/commands/videotest.c +++ b/grub-core/commands/videotest.c @@ -74,6 +74,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), grub_video_create_render_target (&text_layer, width, height, GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA); + if (!text_layer) + goto fail; grub_video_set_active_render_target (text_layer); @@ -191,6 +193,11 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), grub_errno = GRUB_ERR_NONE; return grub_errno; + + fail: + grub_video_delete_render_target (text_layer); + grub_video_restore (); + return grub_errno; } static grub_command_t cmd; From fd261d7300a25e4f4de9e2016147ee686d455f29 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 19:55:27 +0100 Subject: [PATCH 286/315] * grub-core/kern/misc.c (grub_vsnprintf_real): Fix fmt2 parsing. --- ChangeLog | 4 ++++ grub-core/kern/misc.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7ea8d1001..53d151b62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_vsnprintf_real): Fix fmt2 parsing. + 2011-12-13 Vladimir Serbinenko * grub-core/commands/videotest.c (grub_cmd_videotest): Check that diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 128139dc8..0d2ae4bd6 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -749,6 +749,12 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a while (*fmt && grub_isdigit (*fmt)) fmt++; + if (*fmt && *fmt =='.') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + p = fmt; if (*fmt && *fmt == '$') From ace96609b6c5460202f482342f6b3d039a6d4dbb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 19:56:50 +0100 Subject: [PATCH 287/315] * grub-core/kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Support HH22 and HM10 relocations. --- ChangeLog | 5 +++++ grub-core/kern/sparc64/dl.c | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53d151b62..784b4a25e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Support + HH22 and HM10 relocations. + 2011-12-13 Vladimir Serbinenko * grub-core/kern/misc.c (grub_vsnprintf_real): Fix fmt2 parsing. diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c index 7b6266cac..e1be5d9ec 100644 --- a/grub-core/kern/sparc64/dl.c +++ b/grub-core/kern/sparc64/dl.c @@ -111,10 +111,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) & 0x3FFFFFFF); break; + case R_SPARC_HH22: /* 9 V-imm22 */ + *addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF); + break; + case R_SPARC_HM10: /* 12 T-simm13 */ + *addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF); + break; case R_SPARC_HI22: /* 9 V-imm22 */ - if (((grub_int32_t) value) & 0xFF00000000) - return grub_error (GRUB_ERR_BAD_MODULE, - "high address out of 22 bits range"); *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); break; case R_SPARC_LO10: /* 12 T-simm13 */ From 12e9d4d15273af048f333cef72e0944689a0e148 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 20:07:33 +0100 Subject: [PATCH 288/315] Fix video on platforms where unaligned access is forbidden. Make several optimisations while on it. * grub-core/video/fb/fbblit.c (grub_video_fbblit_replace_directN): Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. (grub_video_fbblit_replace_32bit_1bit): Likewise. (grub_video_fbblit_replace_24bit_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: Disable. (grub_video_fbblit_replace_16bit_1bit): Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. (grub_video_fbblit_replace_8bit_1bit): Likewise. (grub_video_fbblit_replace_BGRX8888_RGBX8888): Likewise. (grub_video_fbblit_replace_BGRX8888_RGB888): Likewise. (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. (grub_video_fbblit_replace_BGR888_RGB888): Likewise. (grub_video_fbblit_replace_RGBX8888_RGB88): Likewise. (grub_video_fbblit_replace_RGB888_RGBX888): Likewise. (grub_video_fbblit_replace_RGB888_RGBX8888): Likewise. (grub_video_fbblit_replace_index_RGBX8888): Likewise. (grub_video_fbblit_replace_index_RGB888): Likewise. (grub_video_fbblit_blend_BGRA8888_RGBA8888): Likewise. (grub_video_fbblit_blend_BGR888_RGBA8888): Likewise. (grub_video_fbblit_blend_RGBA8888_RGBA8888): Likewise. (grub_video_fbblit_blend_RGB888_RGBA8888): Likewise. (grub_video_fbblit_blend_index_RGBA8888): Likewise. (grub_video_fbblit_blend_XXXA8888_1bit): Likewise. (grub_video_fbblit_blend_XXX888_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: Disable. (grub_video_fbblit_blend_XXX565_1bit): Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. * grub-core/video/fb/fbfill.c (grub_video_fbfill_direct32): Likewise. * grub-core/video/fb/fbutil.c (grub_video_fb_get_video_ptr): Return void *. * grub-core/video/fb/video_fb.c (common_blitter) [!GRUB_HAVE_UNALIGNED_ACCESS]: Skip disabled blitters. (grub_video_fb_create_render_target_from_pointer) [!GRUB_HAVE_UNALIGNED_ACCESS]: Check alignment. * include/grub/fbutil.h (grub_video_fb_get_video_ptr): Return void *. * include/grub/i386/types.h (GRUB_HAVE_UNALIGNED_ACCESS): New definition. * include/grub/x86_64/types.h (GRUB_HAVE_UNALIGNED_ACCESS): Likewise. --- ChangeLog | 45 ++++++++ grub-core/video/fb/fbblit.c | 204 +++++++++++++++++++++------------- grub-core/video/fb/fbfill.c | 10 +- grub-core/video/fb/fbutil.c | 2 +- grub-core/video/fb/video_fb.c | 13 +++ include/grub/fbutil.h | 13 ++- include/grub/i386/types.h | 2 + include/grub/x86_64/types.h | 2 + 8 files changed, 206 insertions(+), 85 deletions(-) diff --git a/ChangeLog b/ChangeLog index 784b4a25e..2134b481a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2011-12-13 Vladimir Serbinenko + + Fix video on platforms where unaligned access is forbidden. + Make several optimisations while on it. + + * grub-core/video/fb/fbblit.c (grub_video_fbblit_replace_directN): + Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. + (grub_video_fbblit_replace_32bit_1bit): Likewise. + (grub_video_fbblit_replace_24bit_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: + Disable. + (grub_video_fbblit_replace_16bit_1bit): + Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. + (grub_video_fbblit_replace_8bit_1bit): Likewise. + (grub_video_fbblit_replace_BGRX8888_RGBX8888): Likewise. + (grub_video_fbblit_replace_BGRX8888_RGB888): Likewise. + (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_fbblit_replace_BGR888_RGB888): Likewise. + (grub_video_fbblit_replace_RGBX8888_RGB88): Likewise. + (grub_video_fbblit_replace_RGB888_RGBX888): Likewise. + (grub_video_fbblit_replace_RGB888_RGBX8888): Likewise. + (grub_video_fbblit_replace_index_RGBX8888): Likewise. + (grub_video_fbblit_replace_index_RGB888): Likewise. + (grub_video_fbblit_blend_BGRA8888_RGBA8888): Likewise. + (grub_video_fbblit_blend_BGR888_RGBA8888): Likewise. + (grub_video_fbblit_blend_RGBA8888_RGBA8888): Likewise. + (grub_video_fbblit_blend_RGB888_RGBA8888): Likewise. + (grub_video_fbblit_blend_index_RGBA8888): Likewise. + (grub_video_fbblit_blend_XXXA8888_1bit): Likewise. + (grub_video_fbblit_blend_XXX888_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: + Disable. + (grub_video_fbblit_blend_XXX565_1bit): + Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. + * grub-core/video/fb/fbfill.c (grub_video_fbfill_direct32): Likewise. + * grub-core/video/fb/fbutil.c (grub_video_fb_get_video_ptr): Return + void *. + * grub-core/video/fb/video_fb.c (common_blitter) + [!GRUB_HAVE_UNALIGNED_ACCESS]: Skip disabled blitters. + (grub_video_fb_create_render_target_from_pointer) + [!GRUB_HAVE_UNALIGNED_ACCESS]: Check alignment. + * include/grub/fbutil.h (grub_video_fb_get_video_ptr): Return void *. + * include/grub/i386/types.h (GRUB_HAVE_UNALIGNED_ACCESS): New + definition. + * include/grub/x86_64/types.h (GRUB_HAVE_UNALIGNED_ACCESS): Likewise. + 2011-12-13 Vladimir Serbinenko * grub-core/kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Support diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c index 15797be97..4d262d710 100644 --- a/grub-core/video/fb/fbblit.c +++ b/grub-core/video/fb/fbblit.c @@ -80,13 +80,14 @@ grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst, int bpp; bpp = src->mode_info->bytes_per_pixel; + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - grub_memmove (dstptr, srcptr, width * bpp); + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, src->mode_info->pitch); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dst->mode_info->pitch); } } @@ -101,7 +102,7 @@ grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst, int i; int j; grub_uint8_t *srcptr; - grub_uint8_t *dstptr; + grub_uint32_t *dstptr; grub_uint8_t srcmask; unsigned int dstrowskip; unsigned int srcrowskipbyte, srcrowskipbit; @@ -117,7 +118,7 @@ grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -134,9 +135,9 @@ grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst, for (i = 0; i < width; i++) { if (*srcptr & srcmask) - *(grub_uint32_t *) dstptr = fgcolor; + *dstptr = fgcolor; else - *(grub_uint32_t *) dstptr = bgcolor; + *dstptr = bgcolor; srcmask >>= 1; if (!srcmask) { @@ -144,7 +145,7 @@ grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst, srcmask = 0x80; } - dstptr += 4; + dstptr++; } srcptr += srcrowskipbyte; @@ -155,11 +156,12 @@ grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst, srcptr++; srcmask <<= 8 - srcrowskipbit; } - dstptr += dstrowskip; + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } +#ifdef GRUB_HAVE_UNALIGNED_ACCESS /* Optimized replacing blitter for 1-bit to 24-bit. */ void grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst, @@ -187,7 +189,7 @@ grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -247,6 +249,7 @@ grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst, dstptr += dstrowskip; } } +#endif /* Optimized replacing blitter for 1-bit to 16-bit. */ void @@ -259,7 +262,7 @@ grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst, int i; int j; grub_uint8_t *srcptr; - grub_uint8_t *dstptr; + grub_uint16_t *dstptr; grub_uint8_t srcmask; unsigned int dstrowskip; unsigned int srcrowskipbyte, srcrowskipbit; @@ -275,7 +278,7 @@ grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -292,9 +295,9 @@ grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst, for (i = 0; i < width; i++) { if (*srcptr & srcmask) - *(grub_uint16_t *) dstptr = fgcolor; + *dstptr = fgcolor; else - *(grub_uint16_t *) dstptr = bgcolor; + *dstptr = bgcolor; srcmask >>= 1; if (!srcmask) { @@ -302,7 +305,7 @@ grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst, srcmask = 0x80; } - dstptr += 2; + dstptr++; } srcptr += srcrowskipbyte; @@ -313,7 +316,7 @@ grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst, srcptr++; srcmask <<= 8 - srcrowskipbit; } - dstptr += dstrowskip; + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -344,7 +347,7 @@ grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -361,9 +364,9 @@ grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst, for (i = 0; i < width; i++) { if (*srcptr & srcmask) - *(grub_uint8_t *) dstptr = fgcolor; + *dstptr = fgcolor; else - *(grub_uint8_t *) dstptr = bgcolor; + *dstptr = bgcolor; srcmask >>= 1; if (!srcmask) { @@ -406,8 +409,8 @@ grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -449,8 +452,8 @@ grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -493,8 +496,8 @@ grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -516,7 +519,7 @@ grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst, *dstptr++ = sr; } - srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); dstptr += dstrowskip; } } @@ -541,8 +544,8 @@ grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -578,12 +581,16 @@ grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst, unsigned int sr; unsigned int sg; unsigned int sb; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 3 * width; + dstrowskip = dst->mode_info->pitch - 4 * width; + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { sr = *srcptr++; @@ -595,6 +602,8 @@ grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst, *dstptr++ = color; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -614,12 +623,16 @@ grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst, unsigned int sr; unsigned int sg; unsigned int sb; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); + srcrowskip = src->mode_info->pitch - 4 * width; + dstrowskip = dst->mode_info->pitch - 3 * width; for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { color = *srcptr++; @@ -632,6 +645,8 @@ grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst, *dstptr++ = sg; *dstptr++ = sb; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -651,12 +666,17 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst, unsigned int sr; unsigned int sg; unsigned int sb; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 4 * width; + dstrowskip = dst->mode_info->pitch - width; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { color = *srcptr++; @@ -668,6 +688,8 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst, color = grub_video_fb_map_rgb(sr, sg, sb); *dstptr++ = color & 0xFF; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -687,12 +709,17 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst, unsigned int sr; unsigned int sg; unsigned int sb; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 3 * width; + dstrowskip = dst->mode_info->pitch - width; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { sr = *srcptr++; @@ -703,6 +730,8 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst, *dstptr++ = color & 0xFF; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -787,8 +816,8 @@ grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -843,8 +872,8 @@ grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst, *dstptr++ = color; } - srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); - dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -868,8 +897,8 @@ grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst, srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; - srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -924,7 +953,7 @@ grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst, *dstptr++ = dr; } - srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); dstptr += dstrowskip; } } @@ -949,12 +978,17 @@ grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst, unsigned int dr; unsigned int dg; unsigned int db; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 4 * width; + dstrowskip = dst->mode_info->pitch - 4 * width; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { color = *srcptr++; @@ -991,6 +1025,8 @@ grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst, *dstptr++ = color; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -1014,12 +1050,17 @@ grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst, unsigned int dr; unsigned int dg; unsigned int db; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 4 * width; + dstrowskip = dst->mode_info->pitch - 3 * width; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { color = *srcptr++; @@ -1057,6 +1098,8 @@ grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst, *dstptr++ = dg; *dstptr++ = db; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -1081,12 +1124,17 @@ grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst, unsigned char dg; unsigned char db; unsigned char da; + grub_size_t srcrowskip; + grub_size_t dstrowskip; + + srcrowskip = src->mode_info->pitch - 4 * width; + dstrowskip = dst->mode_info->pitch - width; + + srcptr = grub_video_fb_get_video_ptr (src, offset_x, offset_y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { - srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y); - dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j); - for (i = 0; i < width; i++) { color = *srcptr++; @@ -1120,6 +1168,8 @@ grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst, *dstptr++ = color & 0xFF; } + GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } @@ -1134,7 +1184,7 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, int i; int j; grub_uint8_t *srcptr; - grub_uint8_t *dstptr; + grub_uint32_t *dstptr; grub_uint8_t srcmask; unsigned int dstrowskip; unsigned int srcrowskipbyte, srcrowskipbit; @@ -1150,7 +1200,7 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -1181,23 +1231,22 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, } if (a == 255) - *(grub_uint32_t *) dstptr = color; + *dstptr = color; else if (a != 0) { grub_uint8_t s1 = (color >> 0) & 0xFF; grub_uint8_t s2 = (color >> 8) & 0xFF; grub_uint8_t s3 = (color >> 16) & 0xFF; - grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF; - grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF; - grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF; + grub_uint8_t d1 = (*dstptr >> 0) & 0xFF; + grub_uint8_t d2 = (*dstptr >> 8) & 0xFF; + grub_uint8_t d3 = (*dstptr >> 16) & 0xFF; d1 = (d1 * (255 - a) + s1 * a) / 255; d2 = (d2 * (255 - a) + s2 * a) / 255; d3 = (d3 * (255 - a) + s3 * a) / 255; - *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8) - | d1; + *dstptr = (a << 24) | (d3 << 16) | (d2 << 8) | d1; } srcmask >>= 1; @@ -1207,7 +1256,7 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, srcmask = 0x80; } - dstptr += 4; + dstptr++; } srcptr += srcrowskipbyte; @@ -1218,11 +1267,12 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, srcptr++; srcmask <<= 8 - srcrowskipbit; } - dstptr += dstrowskip; + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } /* Optimized blending blitter for 1-bit to XXX888. */ +#ifdef GRUB_HAVE_UNALIGNED_ACCESS void grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst, struct grub_video_fbblit_info *src, @@ -1249,7 +1299,7 @@ grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -1320,6 +1370,7 @@ grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst, dstptr += dstrowskip; } } +#endif /* Optimized blending blitter for 1-bit to XXX888. */ void @@ -1332,7 +1383,7 @@ grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst, int i; int j; grub_uint8_t *srcptr; - grub_uint8_t *dstptr; + grub_uint16_t *dstptr; grub_uint8_t srcmask; unsigned int dstrowskip; unsigned int srcrowskipbyte, srcrowskipbit; @@ -1348,7 +1399,7 @@ grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst, bit_index = offset_y * src->mode_info->width + offset_x; srcptr = (grub_uint8_t *) src->data + (bit_index >> 3); srcmask = 1 << (~bit_index & 7); - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red, src->mode_info->fg_green, @@ -1378,23 +1429,22 @@ grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst, } if (a == 255) - *(grub_uint16_t *) dstptr = color; + *dstptr = color; else if (a != 0) { grub_uint8_t s1 = (color >> 0) & 0x1F; grub_uint8_t s2 = (color >> 5) & 0x3F; grub_uint8_t s3 = (color >> 11) & 0x1F; - grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F; - grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F; - grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F; + grub_uint8_t d1 = (*dstptr >> 0) & 0x1F; + grub_uint8_t d2 = (*dstptr >> 5) & 0x3F; + grub_uint8_t d3 = (*dstptr >> 11) & 0x1F; d1 = (d1 * (255 - a) + s1 * a) / 255; d2 = (d2 * (255 - a) + s2 * a) / 255; d3 = (d3 * (255 - a) + s3 * a) / 255; - *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5) - | ((d3 & 0x1f) << 11); + *dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5) | ((d3 & 0x1f) << 11); } srcmask >>= 1; @@ -1404,7 +1454,7 @@ grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst, srcmask = 0x80; } - dstptr += 2; + dstptr++; } srcptr += srcrowskipbyte; @@ -1415,6 +1465,6 @@ grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst, srcptr++; srcmask <<= 8 - srcrowskipbit; } - dstptr += dstrowskip; + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip); } } diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c index a4ca7c2a1..5f3e55fae 100644 --- a/grub-core/video/fb/fbfill.c +++ b/grub-core/video/fb/fbfill.c @@ -64,7 +64,7 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; /* Get the start address. */ - dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -72,7 +72,7 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, *dstptr++ = color; /* Advance the dest pointer to the right location on the next line. */ - dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip); + GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, rowskip); } } @@ -96,7 +96,7 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; /* Get the start address. */ - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -131,7 +131,7 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; /* Get the start address. */ - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { @@ -164,7 +164,7 @@ grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst, rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; /* Get the start address. */ - dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y); + dstptr = grub_video_fb_get_video_ptr (dst, x, y); for (j = 0; j < height; j++) { diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c index 511beaafc..c7fb08702 100644 --- a/grub-core/video/fb/fbutil.c +++ b/grub-core/video/fb/fbutil.c @@ -31,7 +31,7 @@ #include #include -grub_uint8_t * +void * grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, unsigned int x, unsigned int y) { diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index 2cffcb3d9..2d9d99482 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -622,6 +622,7 @@ common_blitter (struct grub_video_fbblit_info *target, offset_x, offset_y); return; } +#ifdef GRUB_HAVE_UNALIGNED_ACCESS else if (target->mode_info->bpp == 24) { grub_video_fbblit_replace_24bit_1bit (target, source, @@ -629,6 +630,7 @@ common_blitter (struct grub_video_fbblit_info *target, offset_x, offset_y); return; } +#endif else if (target->mode_info->bpp == 16) { grub_video_fbblit_replace_16bit_1bit (target, source, @@ -743,6 +745,7 @@ common_blitter (struct grub_video_fbblit_info *target, offset_x, offset_y); return; } +#ifdef GRUB_HAVE_UNALIGNED_ACCESS else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888 || target->mode_info->blit_format @@ -753,6 +756,7 @@ common_blitter (struct grub_video_fbblit_info *target, offset_x, offset_y); return; } +#endif else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565 || target->mode_info->blit_format @@ -1195,6 +1199,15 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ struct grub_video_fbrender_target *target; unsigned y; +#ifndef GRUB_HAVE_UNALIGNED_ACCESS + if (!(mode_info->bytes_per_pixel & (mode_info->bytes_per_pixel - 1)) + && ((grub_addr_t) ptr & (mode_info->bytes_per_pixel - 1))) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unaligned pointer"); + if (!(mode_info->bytes_per_pixel & (mode_info->bytes_per_pixel - 1)) + && (mode_info->pitch & (mode_info->bytes_per_pixel - 1))) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unaligned pitch"); +#endif + /* Allocate memory for render target. */ target = grub_malloc (sizeof (struct grub_video_fbrender_target)); if (! target) diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h index 065ccf9e3..f68db43b1 100644 --- a/include/grub/fbutil.h +++ b/include/grub/fbutil.h @@ -31,8 +31,17 @@ struct grub_video_fbblit_info grub_uint8_t *data; }; -grub_uint8_t *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y); +void *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, + unsigned int x, unsigned int y); + +/* Advance pointer by VAL bytes. If there is no unaligned access available, + VAL has to be divisible by size of pointed type. + */ +#ifdef GRUB_HAVE_UNALIGNED_ACCESS +#define GRUB_VIDEO_FB_ADVANCE_POINTER(ptr, val) ((ptr) = (typeof (ptr)) ((char *) ptr + val)) +#else +#define GRUB_VIDEO_FB_ADVANCE_POINTER(ptr, val) ((ptr) += (val) / sizeof (*(ptr))) +#endif grub_video_color_t get_pixel (struct grub_video_fbblit_info *source, unsigned int x, unsigned int y); diff --git a/include/grub/i386/types.h b/include/grub/i386/types.h index 0ac64734c..c20063f31 100644 --- a/include/grub/i386/types.h +++ b/include/grub/i386/types.h @@ -28,4 +28,6 @@ /* i386 is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN +#define GRUB_HAVE_UNALIGNED_ACCESS 1 + #endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h index bdee5a109..d53138ea3 100644 --- a/include/grub/x86_64/types.h +++ b/include/grub/x86_64/types.h @@ -28,4 +28,6 @@ /* x86_64 is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN +#define GRUB_HAVE_UNALIGNED_ACCESS 1 + #endif /* ! GRUB_TYPES_CPU_HEADER */ From b453412d2f6a279b35eb6a01d4d1ae13021abdca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 23:10:38 +0100 Subject: [PATCH 289/315] * grub-core/fs/hfs.c (grub_hfs_find_node): Handle unaligned keys. (grub_hfs_iterate_dir): Likewise. --- ChangeLog | 5 +++++ grub-core/fs/hfs.c | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2134b481a..936e64c45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/hfs.c (grub_hfs_find_node): Handle unaligned keys. + (grub_hfs_iterate_dir): Likewise. + 2011-12-13 Vladimir Serbinenko Fix video on platforms where unaligned access is forbidden. diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index 973a2d2ef..6c5c4da3e 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -750,10 +750,7 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key, entry. In case of a non-leaf mode it will be used to lookup the rest of the tree. */ if (cmp <= 0) - { - grub_uint32_t *node = (grub_uint32_t *) rec->data; - found = grub_be_to_cpu32 (*node); - } + found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); else /* The key can not be found in the tree. */ return 1; @@ -817,7 +814,7 @@ grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, struct grub_hfs_catalog_key *ckey = rec->key; if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0) - found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data); + found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); if (hnd->type == 0xFF && ckey->strlen > 0) { From 3c349f5a374330c67b06b1299de8d05123242ce8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 23:11:48 +0100 Subject: [PATCH 290/315] * grub-core/fs/jfs.c (grub_jfs_getent): Handle UTF16 endianness. --- ChangeLog | 4 ++++ grub-core/fs/jfs.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 936e64c45..0928450ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_getent): Handle UTF16 endianness. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/hfs.c (grub_hfs_find_node): Handle unaligned keys. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 3554803cb..72d6fe4c1 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -490,7 +490,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) void addstr (grub_uint16_t *name, int ulen) { while (ulen--) - filename[strpos++] = *(name++); + filename[strpos++] = grub_le_to_cpu16 (*(name++)); } /* The last node, read in more. */ From efc2616ee113b738f7bd8dffba3c533813122ea1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 23:14:25 +0100 Subject: [PATCH 291/315] * grub-core/fs/squash4.c (grub_squash_inode): Fix field sizes. (grub_squash_dirent_header): Likewise. (read_chunk): Don't double swap. (grub_squash_iterate_dir): Fix swap sizes. --- ChangeLog | 7 +++++++ grub-core/fs/squash4.c | 25 ++++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0928450ba..2859e1a7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/squash4.c (grub_squash_inode): Fix field sizes. + (grub_squash_dirent_header): Likewise. + (read_chunk): Don't double swap. + (grub_squash_iterate_dir): Fix swap sizes. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_getent): Handle UTF16 endianness. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 0728287b7..e14df6dbf 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -80,7 +80,8 @@ struct grub_squash_inode grub_uint32_t dummy; grub_uint32_t chunk; grub_uint32_t fragment; - grub_uint32_t offset; + grub_uint16_t offset; + grub_uint16_t dummy2; grub_uint32_t size; grub_uint32_t block_size[0]; } __attribute__ ((packed)) file; @@ -90,8 +91,9 @@ struct grub_squash_inode grub_uint64_t size; grub_uint32_t dummy2[3]; grub_uint32_t fragment; - grub_uint32_t offset; - grub_uint32_t dummy3; + grub_uint16_t offset; + grub_uint16_t dummy3; + grub_uint32_t dummy4; grub_uint32_t block_size[0]; } __attribute__ ((packed)) long_file; struct { @@ -99,8 +101,9 @@ struct grub_squash_inode grub_uint32_t chunk; grub_uint32_t dummy2; grub_uint16_t size; - grub_uint32_t offset; + grub_uint16_t offset; grub_uint16_t dummy3; + grub_uint16_t dummy4; } __attribute__ ((packed)) dir; struct { grub_uint64_t dummy; @@ -124,7 +127,8 @@ struct grub_squash_dirent_header { /* Actually the value is the number of elements - 1. */ grub_uint32_t nelems; - grub_uint64_t ino_chunk; + grub_uint32_t ino_chunk; + grub_uint32_t dummy; } __attribute__ ((packed)); struct grub_squash_dirent @@ -186,10 +190,8 @@ struct grub_fshelp_node static grub_err_t read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, - grub_uint64_t chunk, grub_off_t offset) + grub_uint64_t chunk_start, grub_off_t offset) { - grub_uint64_t chunk_start; - chunk_start = grub_le_to_cpu64 (chunk); while (len > 0) { grub_uint64_t csize; @@ -335,7 +337,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, unsigned i; /* FIXME: why - 3 ? */ - endoff = grub_le_to_cpu32 (dir->ino.dir.size) + off - 3; + endoff = grub_le_to_cpu16 (dir->ino.dir.size) + off - 3; while (off < endoff) { @@ -348,7 +350,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, if (err) return 0; off += sizeof (dh); - for (i = 0; i < (unsigned) grub_le_to_cpu16 (dh.nelems) + 1; i++) + for (i = 0; i < (unsigned) grub_le_to_cpu32 (dh.nelems) + 1; i++) { char *buf; int r; @@ -594,7 +596,8 @@ direct_read (struct grub_squash_data *data, read = grub_le_to_cpu32 (data->sb.block_size) - boff; if (read > len) read = len; - if (!(ino->block_sizes[i] & SQUASH_BLOCK_UNCOMPRESSED)) + if (!(ino->block_sizes[i] + & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED))) err = grub_zlib_disk_read (data->disk, ino->cumulated_block_sizes[i] + a, boff, buf, read); From e7987e1b3bdea7912fdef923418c36800ba8cad7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 13 Dec 2011 23:15:56 +0100 Subject: [PATCH 292/315] * grub-core/fs/romfs.c (grub_romfs_mount): Fix pointer comparison overflow. --- ChangeLog | 5 +++++ grub-core/fs/romfs.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2859e1a7b..d3d7f0ea7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-13 Vladimir Serbinenko + + * grub-core/fs/romfs.c (grub_romfs_mount): Fix pointer comparison + overflow. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/squash4.c (grub_squash_inode): Fix field sizes. diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 76e13727d..11c844e91 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -112,7 +112,7 @@ grub_romfs_mount (grub_device_t dev) if (err) return NULL; for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1) - && ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++) + && ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++) if (!*ptr) break; if ((void *) ptr == &sb + 1) @@ -124,7 +124,7 @@ grub_romfs_mount (grub_device_t dev) if (err) return NULL; for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1) - && ptr < sb.d + grub_be_to_cpu32 (sb.sb.total_size); ptr++) + && ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++) if (!*ptr) break; } From 309e5352316c1c2059cd01b4f8c61e56714df365 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 09:52:00 +0100 Subject: [PATCH 293/315] AFFS never uses unicode. * include/grub/charset.h (GRUB_MAX_UTF8_PER_LATIN1): New const. (grub_latin1_to_utf8): New inline function. * grub-core/fs/affs.c (grub_affs_iterate_dir): Convert latin1 to UTF8. --- ChangeLog | 8 ++++++++ grub-core/fs/affs.c | 18 ++++++++++-------- include/grub/charset.h | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3d7f0ea7..2d811e710 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-12-14 Vladimir Serbinenko + + AFFS never uses unicode. + + * include/grub/charset.h (GRUB_MAX_UTF8_PER_LATIN1): New const. + (grub_latin1_to_utf8): New inline function. + * grub-core/fs/affs.c (grub_affs_iterate_dir): Convert latin1 to UTF8. + 2011-12-13 Vladimir Serbinenko * grub-core/fs/romfs.c (grub_romfs_mount): Fix pointer comparison diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 06f41c4c3..0ad5e6672 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -292,15 +293,15 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, struct grub_affs_data *data = dir->data; grub_uint32_t *hashtable; - auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_uint32_t block, + auto int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block, const struct grub_affs_file *fil); - int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_uint32_t block, + int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block, const struct grub_affs_file *fil) { int type; + grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1]; + node = grub_zalloc (sizeof (*node)); if (!node) { @@ -322,7 +323,10 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, node->di = *fil; node->parent = dir; - if (hook (name, type, node)) + *grub_latin1_to_utf8 (name_u8, fil->name, + grub_min (fil->namelen, sizeof (fil->name))) = '\0'; + + if (hook ((char *) name_u8, type, node)) { grub_free (hashtable); return 1; @@ -377,9 +381,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, if (grub_errno) goto fail; - file.name[file.namelen] = '\0'; - - if (grub_affs_create_node ((char *) (file.name), next, &file)) + if (grub_affs_create_node (next, &file)) return 1; next = grub_be_to_cpu32 (file.next); diff --git a/include/grub/charset.h b/include/grub/charset.h index c7f86a1ef..2b1f54fe8 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -118,6 +118,28 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, return dest; } +#define GRUB_MAX_UTF8_PER_LATIN1 2 + +/* Convert Latin1 to UTF-8. */ +static inline grub_uint8_t * +grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src, + grub_size_t size) +{ + while (size--) + { + if (!(*src & 0x80)) + *dest++ = *src; + else + { + *dest++ = (*src >> 6) | 0xC0; + *dest++ = (*src & 0x3F) | 0x80; + } + src++; + } + + return dest; +} + /* Convert UCS-4 to UTF-8. */ char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size); From cb8f88ea8220ff00d333c27af3463fd2d441f818 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 10:01:24 +0100 Subject: [PATCH 294/315] * include/grub/charset.h (grub_utf16_to_utf8): Make src a const pointer. (grub_ucs4_to_utf8_alloc): Likewise. (grub_ucs4_to_utf8): Likewise. * grub-core/normal/charset.c (grub_ucs4_to_utf8): Likewise. (grub_ucs4_to_utf8_alloc): Likewise. --- ChangeLog | 8 ++++++++ grub-core/normal/charset.c | 6 +++--- include/grub/charset.h | 6 +++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d811e710..90f63fb77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-12-14 Vladimir Serbinenko + + * include/grub/charset.h (grub_utf16_to_utf8): Make src a const pointer. + (grub_ucs4_to_utf8_alloc): Likewise. + (grub_ucs4_to_utf8): Likewise. + * grub-core/normal/charset.c (grub_ucs4_to_utf8): Likewise. + (grub_ucs4_to_utf8_alloc): Likewise. + 2011-12-14 Vladimir Serbinenko AFFS never uses unicode. diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index d089843cc..ee4a7ef5f 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -197,7 +197,7 @@ grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, /* Convert UCS-4 to UTF-8. */ void -grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, +grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, grub_uint8_t *dest, grub_size_t destsize) { /* Keep last char for \0. */ @@ -223,10 +223,10 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, /* Convert UCS-4 to UTF-8. */ char * -grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size) +grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size) { grub_size_t remaining; - grub_uint32_t *ptr; + const grub_uint32_t *ptr; grub_size_t cnt = 0; grub_uint8_t *ret; diff --git a/include/grub/charset.h b/include/grub/charset.h index 2b1f54fe8..b0960c940 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -51,7 +51,7 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, /* Convert UTF-16 to UTF-8. */ static inline grub_uint8_t * -grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, +grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, grub_size_t size) { grub_uint32_t code_high = 0; @@ -141,7 +141,7 @@ grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src, } /* Convert UCS-4 to UTF-8. */ -char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size); +char *grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size); int grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize); @@ -156,7 +156,7 @@ int grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count); void -grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, +grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, grub_uint8_t *dest, grub_size_t destsize); grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, const grub_uint8_t *src, grub_size_t srcsize, From e739d6988502ab3b6e77999aedd7c839d2503355 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 11:13:14 +0100 Subject: [PATCH 295/315] * include/grub/efi/api.h (grub_efi_memory_descriptor): Add packed attribute as the structure isn't guaranteed to be properly aligned. (grub_efi_pci_device_path): Likewise. (grub_efi_pccard_device_path): Likewise. (grub_efi_memory_mapped_device_path): Likewise. Additionaly explicitly specify the size of `memory_type'. (grub_efi_vendor_device_path): Likewise. (grub_efi_controller_device_path): Likewise. (grub_efi_acpi_device_path): Likewise. (grub_efi_expanded_acpi_device_path): Likewise. (grub_efi_atapi_device_path): Likewise. (grub_efi_scsi_device_path): Likewise. (grub_efi_fibre_channel_device_path): Likewise. (grub_efi_1394_device_path): Likewise. (grub_efi_usb_device_path): Likewise. (grub_efi_usb_class_device_path): Likewise. (grub_efi_i2o_device_path): Likewise. (grub_efi_mac_address_device_path): Likewise. (grub_efi_ipv4_device_path): Likewise. (grub_efi_ipv6_device_path): Likewise. (grub_efi_infiniband_device_path): Likewise. (grub_efi_uart_device_path): Likewise. (grub_efi_vendor_messaging_device_path): Likewise. (grub_efi_hard_drive_device_path): Likewise. (grub_efi_cdrom_device_path): Likewise. (grub_efi_vendor_media_device_path): Likewise. (grub_efi_file_path_device_path): Likewise. (grub_efi_protocol_device_path): Likewise. (grub_efi_piwg_device_path): Likewise. (grub_efi_bios_device_path): Likewise. --- ChangeLog | 33 +++++++++++++++++++++++ include/grub/efi/api.h | 60 +++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 90f63fb77..3ba8b3004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2011-12-14 Vladimir Serbinenko + + * include/grub/efi/api.h (grub_efi_memory_descriptor): Add packed + attribute as the structure isn't guaranteed to be properly aligned. + (grub_efi_pci_device_path): Likewise. + (grub_efi_pccard_device_path): Likewise. + (grub_efi_memory_mapped_device_path): Likewise. Additionaly explicitly + specify the size of `memory_type'. + (grub_efi_vendor_device_path): Likewise. + (grub_efi_controller_device_path): Likewise. + (grub_efi_acpi_device_path): Likewise. + (grub_efi_expanded_acpi_device_path): Likewise. + (grub_efi_atapi_device_path): Likewise. + (grub_efi_scsi_device_path): Likewise. + (grub_efi_fibre_channel_device_path): Likewise. + (grub_efi_1394_device_path): Likewise. + (grub_efi_usb_device_path): Likewise. + (grub_efi_usb_class_device_path): Likewise. + (grub_efi_i2o_device_path): Likewise. + (grub_efi_mac_address_device_path): Likewise. + (grub_efi_ipv4_device_path): Likewise. + (grub_efi_ipv6_device_path): Likewise. + (grub_efi_infiniband_device_path): Likewise. + (grub_efi_uart_device_path): Likewise. + (grub_efi_vendor_messaging_device_path): Likewise. + (grub_efi_hard_drive_device_path): Likewise. + (grub_efi_cdrom_device_path): Likewise. + (grub_efi_vendor_media_device_path): Likewise. + (grub_efi_file_path_device_path): Likewise. + (grub_efi_protocol_device_path): Likewise. + (grub_efi_piwg_device_path): Likewise. + (grub_efi_bios_device_path): Likewise. + 2011-12-14 Vladimir Serbinenko * include/grub/charset.h (grub_utf16_to_utf8): Make src a const pointer. diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index b20baa015..7df3602f1 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -371,7 +371,7 @@ struct grub_efi_memory_descriptor grub_efi_virtual_address_t virtual_start; grub_efi_uint64_t num_pages; grub_efi_uint64_t attribute; -}; +} __attribute__ ((packed)); typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t; /* Device Path definitions. */ @@ -416,7 +416,7 @@ struct grub_efi_pci_device_path grub_efi_device_path_t header; grub_efi_uint8_t function; grub_efi_uint8_t device; -}; +} __attribute__ ((packed)); typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t; #define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2 @@ -425,7 +425,7 @@ struct grub_efi_pccard_device_path { grub_efi_device_path_t header; grub_efi_uint8_t function; -}; +} __attribute__ ((packed)); typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; #define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3 @@ -433,10 +433,10 @@ typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; struct grub_efi_memory_mapped_device_path { grub_efi_device_path_t header; - grub_efi_memory_type_t memory_type; + grub_efi_uint32_t memory_type; grub_efi_physical_address_t start_address; grub_efi_physical_address_t end_address; -}; +} __attribute__ ((packed)); typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t; #define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4 @@ -446,7 +446,7 @@ struct grub_efi_vendor_device_path grub_efi_device_path_t header; grub_efi_guid_t vendor_guid; grub_efi_uint8_t vendor_defined_data[0]; -}; +} __attribute__ ((packed)); typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t; #define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5 @@ -455,7 +455,7 @@ struct grub_efi_controller_device_path { grub_efi_device_path_t header; grub_efi_uint32_t controller_number; -}; +} __attribute__ ((packed)); typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t; /* ACPI Device Path. */ @@ -468,7 +468,7 @@ struct grub_efi_acpi_device_path grub_efi_device_path_t header; grub_efi_uint32_t hid; grub_efi_uint32_t uid; -}; +} __attribute__ ((packed)); typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t; #define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2 @@ -479,8 +479,8 @@ struct grub_efi_expanded_acpi_device_path grub_efi_uint32_t hid; grub_efi_uint32_t uid; grub_efi_uint32_t cid; - char hidstr[1]; -}; + char hidstr[0]; +} __attribute__ ((packed)); typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t; #define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ @@ -503,7 +503,7 @@ struct grub_efi_atapi_device_path grub_efi_uint8_t primary_secondary; grub_efi_uint8_t slave_master; grub_efi_uint16_t lun; -}; +} __attribute__ ((packed)); typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t; #define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2 @@ -513,7 +513,7 @@ struct grub_efi_scsi_device_path grub_efi_device_path_t header; grub_efi_uint16_t pun; grub_efi_uint16_t lun; -}; +} __attribute__ ((packed)); typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t; #define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3 @@ -524,7 +524,7 @@ struct grub_efi_fibre_channel_device_path grub_efi_uint32_t reserved; grub_efi_uint64_t wwn; grub_efi_uint64_t lun; -}; +} __attribute__ ((packed)); typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t; #define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4 @@ -534,7 +534,7 @@ struct grub_efi_1394_device_path grub_efi_device_path_t header; grub_efi_uint32_t reserved; grub_efi_uint64_t guid; -}; +} __attribute__ ((packed)); typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t; #define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5 @@ -544,7 +544,7 @@ struct grub_efi_usb_device_path grub_efi_device_path_t header; grub_efi_uint8_t parent_port_number; grub_efi_uint8_t interface; -}; +} __attribute__ ((packed)); typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t; #define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15 @@ -557,7 +557,7 @@ struct grub_efi_usb_class_device_path grub_efi_uint8_t device_class; grub_efi_uint8_t device_subclass; grub_efi_uint8_t device_protocol; -}; +} __attribute__ ((packed)); typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t; #define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6 @@ -566,7 +566,7 @@ struct grub_efi_i2o_device_path { grub_efi_device_path_t header; grub_efi_uint32_t tid; -}; +} __attribute__ ((packed)); typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t; #define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11 @@ -576,7 +576,7 @@ struct grub_efi_mac_address_device_path grub_efi_device_path_t header; grub_efi_mac_address_t mac_address; grub_efi_uint8_t if_type; -}; +} __attribute__ ((packed)); typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t; #define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12 @@ -590,7 +590,7 @@ struct grub_efi_ipv4_device_path grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; -}; +} __attribute__ ((packed)); typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; #define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13 @@ -604,7 +604,7 @@ struct grub_efi_ipv6_device_path grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; -}; +} __attribute__ ((packed)); typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; #define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9 @@ -617,7 +617,7 @@ struct grub_efi_infiniband_device_path grub_efi_uint64_t remote_id; grub_efi_uint64_t target_port_id; grub_efi_uint64_t device_id; -}; +} __attribute__ ((packed)); typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t; #define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14 @@ -630,7 +630,7 @@ struct grub_efi_uart_device_path grub_efi_uint8_t data_bits; grub_efi_uint8_t parity; grub_efi_uint8_t stop_bits; -}; +} __attribute__ ((packed)); typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t; #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 @@ -640,7 +640,7 @@ struct grub_efi_vendor_messaging_device_path grub_efi_device_path_t header; grub_efi_guid_t vendor_guid; grub_efi_uint8_t vendor_defined_data[0]; -}; +} __attribute__ ((packed)); typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t; /* Media Device Path. */ @@ -657,7 +657,7 @@ struct grub_efi_hard_drive_device_path grub_efi_uint8_t partition_signature[8]; grub_efi_uint8_t mbr_type; grub_efi_uint8_t signature_type; -}; +} __attribute__ ((packed)); typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t; #define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2 @@ -668,7 +668,7 @@ struct grub_efi_cdrom_device_path grub_efi_uint32_t boot_entry; grub_efi_lba_t partition_start; grub_efi_lba_t partition_size; -}; +} __attribute__ ((packed)); typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; #define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3 @@ -678,7 +678,7 @@ struct grub_efi_vendor_media_device_path grub_efi_device_path_t header; grub_efi_guid_t vendor_guid; grub_efi_uint8_t vendor_defined_data[0]; -}; +} __attribute__ ((packed)); typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t; #define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4 @@ -687,7 +687,7 @@ struct grub_efi_file_path_device_path { grub_efi_device_path_t header; grub_efi_char16_t path_name[0]; -}; +} __attribute__ ((packed)); typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; #define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5 @@ -696,7 +696,7 @@ struct grub_efi_protocol_device_path { grub_efi_device_path_t header; grub_efi_guid_t guid; -}; +} __attribute__ ((packed)); typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; #define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE 6 @@ -705,7 +705,7 @@ struct grub_efi_piwg_device_path { grub_efi_device_path_t header; grub_efi_guid_t guid __attribute__ ((packed)); -}; +} __attribute__ ((packed)); typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t; @@ -720,7 +720,7 @@ struct grub_efi_bios_device_path grub_efi_uint16_t device_type; grub_efi_uint16_t status_flags; char description[0]; -}; +} __attribute__ ((packed)); typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; struct grub_efi_open_protocol_information_entry From 9f59e9fc36fb0b1efba1da06303c09c18e753934 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 12:05:26 +0100 Subject: [PATCH 296/315] * grub-core/gfxmenu/gui_list.c (draw_menu): Don't use set in if. --- ChangeLog | 4 ++++ grub-core/gfxmenu/gui_list.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ba8b3004..6c69ba780 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-14 Vladimir Serbinenko + + * grub-core/gfxmenu/gui_list.c (draw_menu): Don't use set in if. + 2011-12-14 Vladimir Serbinenko * include/grub/efi/api.h (grub_efi_memory_descriptor): Add packed diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index 2ff6e0f97..1982d9a40 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -245,6 +245,7 @@ draw_menu (list_impl_t self, int num_shown_items) visible_index++, menu_index++) { int is_selected = (menu_index == self->view->selected); + struct grub_video_bitmap *icon; if (is_selected) { @@ -256,8 +257,8 @@ draw_menu (list_impl_t self, int num_shown_items) item_top - sel_toppad); } - struct grub_video_bitmap *icon; - if ((icon = get_item_icon (self, menu_index)) != 0) + icon = get_item_icon (self, menu_index); + if (icon != 0) grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, sel_leftpad, item_top + (item_height - self->icon_height) / 2, From ca1b552c024d320b5e6a3bbe5d4ba4815a9755d1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 14:20:57 +0100 Subject: [PATCH 297/315] * grub-core/gfxmenu/widget-box.c (get_left_pad): Take corners into account. (get_top_pad): Likewise. (get_right_pad): Likewise. (get_bottom_pad): Likewise. --- ChangeLog | 10 ++++++- grub-core/gfxmenu/widget-box.c | 48 +++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c69ba780..c6fbf73f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ 2011-12-14 Vladimir Serbinenko - * grub-core/gfxmenu/gui_list.c (draw_menu): Don't use set in if. + * grub-core/gfxmenu/widget-box.c (get_left_pad): Take corners into + account. + (get_top_pad): Likewise. + (get_right_pad): Likewise. + (get_bottom_pad): Likewise. + +2011-12-14 Vladimir Serbinenko + + * grub-core/gfxmenu/gui_list.c (draw_menu): Don't use assignment in if. 2011-12-14 Vladimir Serbinenko diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c index 41ca7f536..8c9131a24 100644 --- a/grub-core/gfxmenu/widget-box.c +++ b/grub-core/gfxmenu/widget-box.c @@ -188,25 +188,65 @@ get_border_width (grub_gfxmenu_box_t self) static int get_left_pad (grub_gfxmenu_box_t self) { - return get_width (self->raw_pixmaps[BOX_PIXMAP_W]); + int v, c; + + v = get_width (self->raw_pixmaps[BOX_PIXMAP_W]); + c = get_width (self->raw_pixmaps[BOX_PIXMAP_NW]); + if (c > v) + v = c; + c = get_width (self->raw_pixmaps[BOX_PIXMAP_SW]); + if (c > v) + v = c; + + return v; } static int get_top_pad (grub_gfxmenu_box_t self) { - return get_height (self->raw_pixmaps[BOX_PIXMAP_N]); + int v, c; + + v = get_height (self->raw_pixmaps[BOX_PIXMAP_N]); + c = get_height (self->raw_pixmaps[BOX_PIXMAP_NW]); + if (c > v) + v = c; + c = get_height (self->raw_pixmaps[BOX_PIXMAP_NE]); + if (c > v) + v = c; + + return v; } static int get_right_pad (grub_gfxmenu_box_t self) { - return get_width (self->raw_pixmaps[BOX_PIXMAP_E]); + int v, c; + + v = get_width (self->raw_pixmaps[BOX_PIXMAP_E]); + c = get_width (self->raw_pixmaps[BOX_PIXMAP_NE]); + if (c > v) + v = c; + c = get_width (self->raw_pixmaps[BOX_PIXMAP_SE]); + if (c > v) + v = c; + + return v; } static int get_bottom_pad (grub_gfxmenu_box_t self) { - return get_height (self->raw_pixmaps[BOX_PIXMAP_S]); + int v, c; + + v = get_height (self->raw_pixmaps[BOX_PIXMAP_S]); + c = get_height (self->raw_pixmaps[BOX_PIXMAP_SW]); + if (c > v) + v = c; + c = get_height (self->raw_pixmaps[BOX_PIXMAP_SE]); + if (c > v) + v = c; + + return v; } static void From a14b16d1f95aa7fbb8e223f44b7681cec78d550f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 23:57:35 +0100 Subject: [PATCH 298/315] * include/grub/types.h (GRUB_PROPERLY_ALIGNED_ARRAY): Add missing brackets. --- ChangeLog | 11 +++++------ include/grub/types.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6fbf73f0..bb00e383e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-14 Vladimir Serbinenko + + * include/grub/types.h (GRUB_PROPERLY_ALIGNED_ARRAY): Add missing + brackets. + 2011-12-14 Vladimir Serbinenko * grub-core/gfxmenu/widget-box.c (get_left_pad): Take corners into @@ -344,12 +349,6 @@ (grub_nilfs2_btree_node_dkeys): Ensure return pointer alignment. (grub_nilfs2_btree_lookup): Ensure buffer alignment. -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext4_find_leaf): MAke buf as pointer to - properly aligned memory. - (grub_ext2_read_block): Ensure buffer alignment. - 2011-12-13 Vladimir Serbinenko * grub-core/fs/romfs.c (grub_romfs_iterate_dir): Properly align diff --git a/include/grub/types.h b/include/grub/types.h index e61a9a5c6..19a09895b 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -142,7 +142,7 @@ typedef grub_int32_t grub_ssize_t; typedef grub_uint64_t grub_properly_aligned_t; -#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[(size + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] +#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] /* The type for representing a file offset. */ typedef grub_uint64_t grub_off_t; From 7a7f7cc9c3ed7f614fb98df18f1c4035a36ce5d1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 14 Dec 2011 23:59:11 +0100 Subject: [PATCH 299/315] * include/grub/kernel.h (FOR_MODULES): Make it a bit faster. --- ChangeLog | 4 ++++ include/grub/kernel.h | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb00e383e..ecc637e63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-14 Vladimir Serbinenko + + * include/grub/kernel.h (FOR_MODULES): Make it a bit faster. + 2011-12-14 Vladimir Serbinenko * include/grub/types.h (GRUB_PROPERLY_ALIGNED_ARRAY): Add missing diff --git a/include/grub/kernel.h b/include/grub/kernel.h index c9a549675..4c8b29c8b 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -71,15 +71,13 @@ struct grub_module_info64 extern grub_addr_t EXPORT_VAR (grub_modbase); -#define FOR_MODULES(var) for (var = grub_modbase ? (struct grub_module_header *) \ +#define FOR_MODULES(var) for (\ + var = grub_modbase ? (struct grub_module_header *) \ (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ var && (grub_addr_t) var \ < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ var = (struct grub_module_header *) \ - ((grub_uint32_t *) var \ - + ((((struct grub_module_header *) var)->size \ - + sizeof (grub_uint32_t) - 1) \ - / sizeof (grub_uint32_t)))) + ((grub_uint32_t *) var + ((struct grub_module_header *) var)->size / 4)) grub_addr_t grub_modules_get_end (void); From ee9c2e7a978cf5dd5f6eb84341ab356a87769bd3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 02:20:21 +0100 Subject: [PATCH 300/315] * grub-core/lib/reed_solomon.c (init_powx): Set gf_powx_inv[0] just to be deterministic. (syndroms): Compute 0 syndrom. (rs_recover): Use 0 syndrom. --- ChangeLog | 7 +++++++ grub-core/lib/reed_solomon.c | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecc637e63..5a654270d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-14 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (init_powx): Set gf_powx_inv[0] just to + be deterministic. + (syndroms): Compute 0 syndrom. + (rs_recover): Use 0 syndrom. + 2011-12-14 Vladimir Serbinenko * include/grub/kernel.h (FOR_MODULES): Make it a bit faster. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 7da5f204c..fc5443c28 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -89,6 +89,7 @@ init_powx (void) int i; grub_uint8_t cur = 1; + gf_powx_inv[0] = 0; for (i = 0; i < 255; i++) { gf_powx[i] = cur; @@ -165,7 +166,8 @@ syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs, { gf_single_t xn = 1; unsigned i; - for (i = 0; i < rs; i++) + sy[0] = pol_evaluate (m, s + rs - 1, xn); + for (i = 1; i < rs; i++) { if (xn & (1 << (GF_SIZE - 1))) { @@ -344,7 +346,7 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) #endif for (j = 0; j < errnum; j++) - eq[j] = errpot[j]; + eq[j] = 1; eq[errnum] = sy[0]; for (i = 1; i < (int) rs; i++) { @@ -530,7 +532,7 @@ main (int argc, char **argv) out = fopen ("tst_rs.bin", "wb"); fwrite (buf, 1, s + rs, out); fclose (out); -#if 0 +#if 1 grub_memset (buf + 512 * 15, 0, 512); #endif From b81d609e4c9f3e8f4534c38804305979d687b2dc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:17:36 +0100 Subject: [PATCH 301/315] * grub-core/kern/i386/realmode.S: Increase alignment. * grub-core/boot/i386/pc/startup_raw.S: Likewise. --- grub-core/boot/i386/pc/startup_raw.S | 2 +- grub-core/kern/i386/realmode.S | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 9e0f23d71..3fae1e4e1 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -341,6 +341,6 @@ gate_a20_check_state: #include "lzma_decode.S" #endif - .p2align 2 + .p2align 4 LOCAL(decompressor_end): diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 2e16847c8..36d41e7de 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -46,7 +46,7 @@ * This is the area for all of the special variables. */ - .p2align 2 /* force 4-byte alignment */ + .p2align 5 /* force 4-byte alignment */ protstack: .long GRUB_MEMORY_MACHINE_PROT_STACK @@ -79,7 +79,7 @@ protstack: * description. */ - .p2align 2 /* force 4-byte alignment */ + .p2align 5 /* force 4-byte alignment */ gdt: .word 0, 0 .byte 0, 0, 0, 0 @@ -113,6 +113,7 @@ gdt: .byte 0, 0x92, 0, 0 + .p2align 5 /* this is the GDT descriptor */ gdtdesc: .word 0x27 /* limit */ From e3fd394a10a709e4935c3a64b237dada17f01b8e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:20:41 +0100 Subject: [PATCH 302/315] * grub-core/boot/i386/pc/startup_raw.S: Move realmode routines to non-RS part to avoid RS messing with GDT. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Increase to suit in realmode routines. --- ChangeLog | 12 ++++++++++++ grub-core/boot/i386/pc/startup_raw.S | 4 ++-- include/grub/offsets.h | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a654270d..c3c3b1c36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/boot/i386/pc/startup_raw.S: Move realmode routines to + non-RS part to avoid RS messing with GDT. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): + Increase to suit in realmode routines. + +2011-12-15 Vladimir Serbinenko + + * grub-core/kern/i386/realmode.S: Increase alignment. + * grub-core/boot/i386/pc/startup_raw.S: Likewise. + 2011-12-14 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (init_powx): Set gf_powx_inv[0] just to diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 3fae1e4e1..ade2883b0 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -108,6 +108,8 @@ LOCAL (codestart): call EXT_C (grub_reed_solomon_recover) jmp post_reed_solomon +#include "../../../kern/i386/realmode.S" + #include .text @@ -185,8 +187,6 @@ post_reed_solomon: movl $real_to_prot, %ecx jmp *%esi -#include "../../../kern/i386/realmode.S" - /* * grub_gate_a20(int on) * diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 68ed084cb..75a46e128 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -28,7 +28,7 @@ /* Offset of reed_solomon_redundancy. */ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x7e0 /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 From 276b7a8bddaca261070b5f6658352dbbcd497f2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:22:36 +0100 Subject: [PATCH 303/315] * grub-core/boot/i386/pc/startup_raw.S: Clear direction flag for certainety. --- ChangeLog | 5 +++++ grub-core/boot/i386/pc/startup_raw.S | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index c3c3b1c36..c59df38c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/boot/i386/pc/startup_raw.S: Clear direction flag for + certainety. + 2011-12-15 Vladimir Serbinenko * grub-core/boot/i386/pc/startup_raw.S: Move realmode routines to diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index ade2883b0..9c044ffb0 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -99,12 +99,14 @@ LOCAL (codestart): .code32 incl %eax + cld call grub_gate_a20 movl LOCAL(compressed_size), %edx addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - _start), %edx movl reed_solomon_redundancy, %ecx leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax + cld call EXT_C (grub_reed_solomon_recover) jmp post_reed_solomon From 96f8caf81275c7598e5fe40a3cd40699100846a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:27:01 +0100 Subject: [PATCH 304/315] * grub-core/lib/reed_solomon.c (decode_block): Allocate on heap and not stack. (encode_block): Likewise. --- ChangeLog | 6 ++++++ grub-core/lib/reed_solomon.c | 23 +++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c59df38c2..0063cdf04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (decode_block): Allocate on heap and not + stack. + (encode_block): Likewise. + 2011-12-15 Vladimir Serbinenko * grub-core/boot/i386/pc/startup_raw.S: Clear direction flag for diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index fc5443c28..3d8bb9e1f 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -390,12 +390,19 @@ decode_block (gf_single_t *ptr, grub_size_t s, { 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]; + gf_single_t *m; /* Nothing to do. */ if (!ds || !rr) continue; +#ifndef STANDALONE + m = xmalloc (ds + rr); +#else + m = (gf_single_t *) scratch; + scratch += ds + rr; +#endif + for (j = 0; j < (int) ds; j++) m[j] = ptr[SECTOR_SIZE * j + i]; for (j = 0; j < (int) rr; j++) @@ -405,6 +412,12 @@ decode_block (gf_single_t *ptr, grub_size_t s, for (j = 0; j < (int) ds; j++) ptr[SECTOR_SIZE * j + i] = m[j]; + +#ifndef STANDALONE + free (m); +#else + scratch -= ds + rr; +#endif } } @@ -418,12 +431,18 @@ encode_block (gf_single_t *ptr, grub_size_t s, { 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]; + gf_single_t *m; + + if (!ds || !rr) + continue; + + m = xmalloc (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]; + free (m); } } #endif From 384ad7cc1b08beacd709e1b51e84feaee3d2c978 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:32:41 +0100 Subject: [PATCH 305/315] * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Fix current address calculation. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsdXX.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0063cdf04..2bd1aa287 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Fix + current address calculation. + 2011-12-15 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (decode_block): Allocate on heap and not diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index 92d267534..7cec7a8ef 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -244,16 +244,16 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, curload = module + s->sh_addr + s->sh_size; } - load (file, UINT_TO_PTR (module), 0, sizeof (e)); + load (file, (grub_uint8_t *) chunk_src + module - *kern_end, 0, sizeof (e)); if (curload < module + sizeof (e)) curload = module + sizeof (e); - load (file, UINT_TO_PTR (curload), e.e_shoff, + load (file, (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff, e.e_shnum * e.e_shentsize); e.e_shoff = curload - module; curload += e.e_shnum * e.e_shentsize; - load (file, UINT_TO_PTR (curload), e.e_phoff, + load (file, (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff, e.e_phnum * e.e_phentsize); e.e_phoff = curload - module; curload += e.e_phnum * e.e_phentsize; From c476e6df168aaa6b9eb3be07060cb25e3ad6dca7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:35:54 +0100 Subject: [PATCH 306/315] * grub-core/gfxmenu/gui_label.c (label_paint): Handle the case text_width > available width a bit more gracefully. --- ChangeLog | 5 +++++ grub-core/gfxmenu/gui_label.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2bd1aa287..ff54cfe78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/gfxmenu/gui_label.c (label_paint): Handle the case + text_width > available width a bit more gracefully. + 2011-12-15 Vladimir Serbinenko * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Fix diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c index a7dc95afc..688bea077 100644 --- a/grub-core/gfxmenu/gui_label.c +++ b/grub-core/gfxmenu/gui_label.c @@ -94,15 +94,17 @@ label_paint (void *vself, const grub_video_rect_t *region) if (self->align == align_left) left_x = 0; else if (self->align == align_center) - left_x = ((self->bounds.width - - grub_font_get_string_width (self->font, self->text)) - ) / 2; + left_x = (self->bounds.width + - grub_font_get_string_width (self->font, self->text)) / 2; else if (self->align == align_right) left_x = (self->bounds.width - grub_font_get_string_width (self->font, self->text)); else return; /* Invalid alignment. */ + if (left_x < 0 || left_x > (int) self->bounds.width) + left_x = 0; + grub_video_rect_t vpsave; grub_gui_set_viewport (&self->bounds, &vpsave); grub_font_draw_string (self->text, From 5ef5c511475d74a10ff11a9600aee559fe7ec29c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:39:41 +0100 Subject: [PATCH 307/315] * util/grub-mkimage.c (generate_image): Decrease the higher limit because of stack. * util/grub-setup.c (setup): Don't add redundancy past the higher load limit. --- ChangeLog | 7 +++++++ util/grub-mkimage.c | 6 +++--- util/grub-setup.c | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff54cfe78..6931c1b55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-15 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Decrease the higher limit + because of stack. + * util/grub-setup.c (setup): Don't add redundancy past the higher load + limit. + 2011-12-15 Vladimir Serbinenko * grub-core/gfxmenu/gui_label.c (label_paint): Handle the case diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 0ffeb909e..de43c4493 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -958,10 +958,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *boot_path, *boot_img; size_t boot_size; - if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000) + grub_util_error (_("core image is too big (0x%x > 0x%x)"), GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, - GRUB_MEMORY_I386_PC_UPPER); + 0x78000); num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); if (num > 0xffff) diff --git a/util/grub-setup.c b/util/grub-setup.c index 055543f2d..d3b3b7520 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -412,6 +412,10 @@ setup (const char *dir, if (nsec > 2 * core_sectors) nsec = 2 * core_sectors; + if (nsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS)) + nsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS); /* Clean out the blocklists. */ block = first_block; From f2b60fbdb8f384274ea8f3b7e29469a9613d0b77 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 19:59:49 +0100 Subject: [PATCH 308/315] Replace UINT_TO_PTR and PTR_TO_UINT with explicit grub_addr_t casts. * include/grub/types.h (UINT_TO_PTR): Removed. All users switched to grub_addr_t casts. (PTR_TO_UINT64): Likewise. (PTR_TO_UINT32): Likewise. --- ChangeLog | 9 +++++++++ grub-core/commands/acpi.c | 26 +++++++++++++------------- grub-core/efiemu/mm.c | 4 ++-- grub-core/efiemu/prepare.c | 5 ++--- grub-core/efiemu/symbols.c | 14 +++++++------- grub-core/loader/i386/xnu.c | 30 +++++++++++++++--------------- grub-core/mmap/i386/mmap.c | 6 +++--- grub-core/mmap/i386/pc/mmap.c | 4 ++-- include/grub/efiemu/efiemu.h | 4 ++-- include/grub/types.h | 10 ---------- 10 files changed, 55 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6931c1b55..1ce7fce0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-12-15 Vladimir Serbinenko + + Replace UINT_TO_PTR and PTR_TO_UINT with explicit grub_addr_t casts. + + * include/grub/types.h (UINT_TO_PTR): Removed. All users switched to + grub_addr_t casts. + (PTR_TO_UINT64): Likewise. + (PTR_TO_UINT32): Likewise. + 2011-12-15 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Decrease the higher limit diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index f394e3233..2531b8e11 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -166,7 +166,7 @@ grub_acpi_create_ebda (void) return 0; } - ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4); + ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4); ebda_kb_len = *(grub_uint16_t *) ebda; if (! ebda || ebda_kb_len > 16) ebda_kb_len = 0; @@ -174,14 +174,14 @@ grub_acpi_create_ebda (void) /* FIXME: use low-memory mm allocation once it's available. */ grub_mmap_iterate (find_hook); - targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow); + targetebda = (grub_uint8_t *) (grub_addr_t) highestlow; grub_dprintf ("acpi", "creating ebda @%llx\n", (unsigned long long) highestlow); if (! highestlow) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't find space for the new EBDA"); - mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len, + mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ebda_len, GRUB_MEMORY_RESERVED); if (! mmapregion) return grub_errno; @@ -330,13 +330,13 @@ setup_common_tables (void) if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE, sizeof (fadt->hdr.signature)) == 0) { - fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt); + fadt->dsdt_addr = (grub_addr_t) table_dsdt; fadt->facs_addr = facs_addr; /* Does a revision 2 exist at all? */ if (fadt->hdr.revision >= 3) { - fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt); + fadt->dsdt_xaddr = (grub_addr_t) table_dsdt; fadt->facs_xaddr = facs_addr; } @@ -367,7 +367,7 @@ setup_common_tables (void) rsdt->creator_rev = root_creator_rev; for (cur = acpi_tables; cur; cur = cur->next) - *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr); + *(rsdt_entry++) = (grub_addr_t) cur->addr; /* Recompute checksum. */ rsdt->checksum = 0; @@ -385,7 +385,7 @@ setv1table (void) sizeof (rsdpv1_new->signature)); grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid)); rsdpv1_new->revision = 0; - rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr); + rsdpv1_new->rsdt_addr = (grub_addr_t) rsdt_addr; rsdpv1_new->checksum = 0; rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new, sizeof (*rsdpv1_new)); @@ -410,7 +410,7 @@ setv2table (void) xsdt_entry = (grub_uint64_t *)(xsdt + 1); for (cur = acpi_tables; cur; cur = cur->next) - *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr); + *(xsdt_entry++) = (grub_addr_t) cur->addr; grub_memcpy (&(xsdt->signature), "XSDT", 4); xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables; xsdt->revision = 1; @@ -430,12 +430,12 @@ setv2table (void) grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid, sizeof (rsdpv2_new->rsdpv1.oemid)); rsdpv2_new->rsdpv1.revision = rev2; - rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr); + rsdpv2_new->rsdpv1.rsdt_addr = (grub_addr_t) rsdt_addr; rsdpv2_new->rsdpv1.checksum = 0; rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum (&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1)); rsdpv2_new->length = sizeof (*rsdpv2_new); - rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt); + rsdpv2_new->xsdt_addr = (grub_addr_t) xsdt; rsdpv2_new->checksum = 0; rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new, rsdpv2_new->length); @@ -507,7 +507,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) /* Set revision variables to replicate the same version as host. */ rev1 = ! rsdp->revision; rev2 = rsdp->revision; - rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr); + rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr; /* Load host tables. */ for (entry_ptr = (grub_uint32_t *) (rsdt + 1); entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) @@ -517,7 +517,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) char signature[5]; struct efiemu_acpi_table *table; struct grub_acpi_table_header *curtable - = (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr); + = (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr; signature[4] = 0; for (i = 0; i < 4;i++) signature[i] = grub_tolower (curtable->signature[i]); @@ -541,7 +541,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) /* Load DSDT if not excluded. */ dsdt = (struct grub_acpi_table_header *) - UINT_TO_PTR (fadt->dsdt_addr); + (grub_addr_t) fadt->dsdt_addr; if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt")) && (! load_only || grub_strword (load_only, "dsdt")) && dsdt->length >= sizeof (*dsdt)) diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index 7bb7cc080..f9596f124 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -201,10 +201,10 @@ efiemu_alloc_requests (void) - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE); if (align_overhead == GRUB_EFIEMU_PAGESIZE) align_overhead = 0; - curptr = ((grub_uint8_t *)curptr) + align_overhead; + curptr = ((grub_uint8_t *) curptr) + align_overhead; /* Add the region to memory map */ - grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart), + grub_efiemu_add_to_mmap ((grub_addr_t) typestart, curptr - typestart, reqorder[i]); } diff --git a/grub-core/efiemu/prepare.c b/grub-core/efiemu/prepare.c index 171e092c9..5c3146490 100644 --- a/grub-core/efiemu/prepare.c +++ b/grub-core/efiemu/prepare.c @@ -97,10 +97,9 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid), sizeof (cur->guid)); if (cur->get_table) - conftables[i].vendor_table - = PTR_TO_UINT64 (cur->get_table (cur->data)); + conftables[i].vendor_table = (grub_addr_t) cur->get_table (cur->data); else - conftables[i].vendor_table = PTR_TO_UINT64 (cur->data); + conftables[i].vendor_table = (grub_addr_t) cur->data; } err = SUFFIX (grub_efiemu_crc) (); diff --git a/grub-core/efiemu/symbols.c b/grub-core/efiemu/symbols.c index 4fc546b59..7137fcbd9 100644 --- a/grub-core/efiemu/symbols.c +++ b/grub-core/efiemu/symbols.c @@ -169,7 +169,7 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, else ptv_rels[ptv_written].plustype = 0; - ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr); + ptv_rels[ptv_written].addr = (grub_addr_t) addr; ptv_rels[ptv_written].size = size; ptv_written++; @@ -179,10 +179,10 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, /* Compute the value */ if (minus_handle) - value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle)); + value -= (grub_addr_t) grub_efiemu_mm_obtain_request (minus_handle); if (plus_handle) - value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle)); + value += (grub_addr_t) grub_efiemu_mm_obtain_request (plus_handle); /* Write the value */ switch (size) @@ -248,16 +248,16 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, switch (cur_relloc->size) { case 8: - *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + *((grub_uint64_t *) (grub_addr_t) cur_relloc->addr) += corr; break; case 4: - *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + *((grub_uint32_t *) (grub_addr_t) cur_relloc->addr) += corr; break; case 2: - *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + *((grub_uint16_t *) (grub_addr_t) cur_relloc->addr) += corr; break; case 1: - *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; + *((grub_uint8_t *) (grub_addr_t) cur_relloc->addr) += corr; break; } } diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 4d3678ea1..98b635911 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -734,18 +734,18 @@ grub_cpu_xnu_fill_devicetree (void) #else if (SIZEOF_OF_UINTN == 4) { - ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *) - SYSTEM_TABLE_PTR (configuration_table))[i] - .vendor_table); + ptr = (void *) (grub_addr_t) ((grub_efiemu_configuration_table32_t *) + SYSTEM_TABLE_PTR (configuration_table))[i] + .vendor_table; guid = ((grub_efiemu_configuration_table32_t *) SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid; } else { - ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *) - SYSTEM_TABLE_PTR (configuration_table))[i] - .vendor_table); + ptr = (void *) (grub_addr_t) ((grub_efiemu_configuration_table64_t *) + SYSTEM_TABLE_PTR (configuration_table))[i] + .vendor_table; guid = ((grub_efiemu_configuration_table64_t *) SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid; @@ -786,9 +786,9 @@ grub_cpu_xnu_fill_devicetree (void) if (! curval->data) return grub_errno; if (SIZEOF_OF_UINTN == 4) - *((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr); + *((grub_uint32_t *) curval->data) = (grub_addr_t) ptr; else - *((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr); + *((grub_uint64_t *) curval->data) = (grub_addr_t) ptr; /* Create alias. */ for (j = 0; j < sizeof (table_aliases) / sizeof (table_aliases[0]); j++) @@ -821,10 +821,10 @@ grub_cpu_xnu_fill_devicetree (void) return grub_errno; if (SIZEOF_OF_UINTN == 4) *((grub_uint32_t *) curval->data) - = PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services)); + = (grub_addr_t) SYSTEM_TABLE_PTR (runtime_services); else *((grub_uint64_t *) curval->data) - = PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services)); + = (grub_addr_t) SYSTEM_TABLE_PTR (runtime_services); return GRUB_ERR_NONE; } @@ -939,7 +939,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) params->lfb_depth = mode_info.bpp; params->lfb_line_len = mode_info.pitch; - params->lfb_base = PTR_TO_UINT32 (framebuffer); + params->lfb_base = (grub_addr_t) framebuffer; params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; @@ -1057,7 +1057,7 @@ grub_xnu_boot (void) if (err) return err; - bootparams->efi_system_table = PTR_TO_UINT32 (grub_autoefi_system_table); + bootparams->efi_system_table = (grub_addr_t) grub_autoefi_system_table; firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1) @@ -1077,11 +1077,11 @@ grub_xnu_boot (void) curdesc->virtual_start = curruntimepage << 12; curruntimepage += curdesc->num_pages; if (curdesc->physical_start - <= PTR_TO_UINT64 (grub_autoefi_system_table) + <= (grub_addr_t) grub_autoefi_system_table && curdesc->physical_start + (curdesc->num_pages << 12) - > PTR_TO_UINT64 (grub_autoefi_system_table)) + > (grub_addr_t) grub_autoefi_system_table) bootparams->efi_system_table - = PTR_TO_UINT64 (grub_autoefi_system_table) + = (grub_addr_t) grub_autoefi_system_table - curdesc->physical_start + curdesc->virtual_start; if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit) curdesc->virtual_start |= 0xffffff8000000000ULL; diff --git a/grub-core/mmap/i386/mmap.c b/grub-core/mmap/i386/mmap.c index e9c030b7b..648a7df4b 100644 --- a/grub-core/mmap/i386/mmap.c +++ b/grub-core/mmap/i386/mmap.c @@ -54,7 +54,7 @@ grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, { /* FIXME: use low-memory mm allocation once it's available. */ grub_mmap_iterate (find_hook); - ret = UINT_TO_PTR (highestlow); + ret = (void *) (grub_addr_t) highestlow; } else ret = grub_memalign (align, size); @@ -65,7 +65,7 @@ grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, return 0; } - *handle = grub_mmap_register (PTR_TO_UINT64 (ret), size, type); + *handle = grub_mmap_register ((grub_addr_t) ret, size, type); if (! *handle) { grub_free (ret); @@ -93,7 +93,7 @@ grub_mmap_free_and_unregister (int handle) grub_mmap_unregister (handle); if (addr >= 0x100000) - grub_free (UINT_TO_PTR (addr)); + grub_free ((void *) (grub_addr_t) addr); } #endif diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c index baa41aa2d..7f170b65d 100644 --- a/grub-core/mmap/i386/pc/mmap.c +++ b/grub-core/mmap/i386/pc/mmap.c @@ -101,8 +101,8 @@ preboot (int noreturn __attribute__ ((unused))) grub_memcpy (hooktarget, &grub_machine_mmaphook_start, &grub_machine_mmaphook_end - &grub_machine_mmaphook_start); - *((grub_uint16_t *) 0x4a) = PTR_TO_UINT32 (hooktarget) >> 4; - *((grub_uint16_t *) 0x56) = PTR_TO_UINT32 (hooktarget) >> 4; + *((grub_uint16_t *) 0x4a) = ((grub_addr_t) hooktarget) >> 4; + *((grub_uint16_t *) 0x56) = ((grub_addr_t) hooktarget) >> 4; *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12 - &grub_machine_mmaphook_start; *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15 diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index ec35dac5a..530e18c82 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -114,9 +114,9 @@ extern grub_efi_system_table64_t *grub_efiemu_system_table64; : (grub_efiemu_system_table32->x \ = (y))) #define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_efiemu_sizeof_uintn_t () == 8)\ - ? UINT_TO_PTR \ + ? (void *) (grub_addr_t) \ (grub_efiemu_system_table64->x) \ - : UINT_TO_PTR \ + : (void *) (grub_addr_t) \ (grub_efiemu_system_table32->x)) #define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_efiemu_sizeof_uintn_t () == 8) \ ? (void *) \ diff --git a/include/grub/types.h b/include/grub/types.h index 19a09895b..f8059c1ab 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -130,16 +130,6 @@ typedef grub_int32_t grub_ssize_t; # define GRUB_LONG_MIN (-2147483647L - 1) #endif -#if GRUB_CPU_SIZEOF_VOID_P == 4 -#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x)) -#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x)) -#define PTR_TO_UINT32(x) ((grub_uint32_t)(x)) -#else -#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x)) -#define PTR_TO_UINT64(x) ((grub_uint64_t)(x)) -#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x)) -#endif - typedef grub_uint64_t grub_properly_aligned_t; #define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] From 3a38c6723540a39bc3e93d2b43423d899f5422ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:04:21 +0100 Subject: [PATCH 309/315] forgotten file for previous commit --- grub-core/mmap/efi/mmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 8e5cce0d0..b34a3ba30 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -272,7 +272,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), overlays = curover; *handle = curover->handle; - return UINT_TO_PTR (curover->address); + return (void *) (grub_addr_t) curover->address; } void From 813c0a2be82a00d4117d8071ae9e6a074d7672f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:05:27 +0100 Subject: [PATCH 310/315] * grub-core/loader/multiboot.c (grub_cmd_module): Fix target address. --- ChangeLog | 4 ++++ grub-core/loader/multiboot.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1ce7fce0e..009d52f08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/loader/multiboot.c (grub_cmd_module): Fix target address. + 2011-12-15 Vladimir Serbinenko Replace UINT_TO_PTR and PTR_TO_UINT with explicit grub_addr_t casts. diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 2de8e0909..f76123e67 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -309,7 +309,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), return err; } module = get_virtual_current_address (ch); - target = (grub_addr_t) get_virtual_current_address (ch); + target = get_physical_target_address (ch); } err = grub_multiboot_add_module (target, size, argc - 1, argv + 1); From 8e54b4b76ab5df4754ef31a44803e2d085dd3850 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:20:02 +0100 Subject: [PATCH 311/315] * grub-core/lib/libgcrypt/cipher/serpent.c (serpent_key_prepare): Fix misaligned access. (serpent_setkey): Likewise. (serpent_encrypt_internal): Likewise. (serpent_decrypt_internal): Likewise. (serpent_encrypt): Don't put an alignment-increasing cast. (serpent_decrypt): Likewise. (serpent_test): Likewise. --- ChangeLog | 11 +++ grub-core/lib/libgcrypt/cipher/serpent.c | 91 +++++++++--------------- 2 files changed, 45 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index 009d52f08..7f44d38ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/lib/libgcrypt/cipher/serpent.c (serpent_key_prepare): Fix + misaligned access. + (serpent_setkey): Likewise. + (serpent_encrypt_internal): Likewise. + (serpent_decrypt_internal): Likewise. + (serpent_encrypt): Don't put an alignment-increasing cast. + (serpent_decrypt): Likewise. + (serpent_test): Likewise. + 2011-12-15 Vladimir Serbinenko * grub-core/loader/multiboot.c (grub_cmd_module): Fix target address. diff --git a/grub-core/lib/libgcrypt/cipher/serpent.c b/grub-core/lib/libgcrypt/cipher/serpent.c index 6b7e655a9..b1026eafc 100644 --- a/grub-core/lib/libgcrypt/cipher/serpent.c +++ b/grub-core/lib/libgcrypt/cipher/serpent.c @@ -585,22 +585,19 @@ serpent_key_prepare (const byte *key, unsigned int key_length, int i; /* Copy key. */ - for (i = 0; i < key_length / 4; i++) - { + memcpy (key_prepared, key, key_length); #ifdef WORDS_BIGENDIAN - key_prepared[i] = byte_swap_32 (((u32 *) key)[i]); -#else - key_prepared[i] = ((u32 *) key)[i]; + for (i = 0; i < key_length / 4; i++) + key_prepared[i] = byte_swap_32 (key_prepared[i]); #endif - } - if (i < 8) + if (key_length < 32) { /* Key must be padded according to the Serpent specification. */ - key_prepared[i] = 0x00000001; + key_prepared[key_length / 4] = 0x00000001; - for (i++; i < 8; i++) + for (i = key_length / 4 + 1; i < 8; i++) key_prepared[i] = 0; } } @@ -707,21 +704,17 @@ serpent_setkey (void *ctx, static void serpent_encrypt_internal (serpent_context_t *context, - const serpent_block_t input, serpent_block_t output) + const byte *input, byte *output) { serpent_block_t b, b_next; int round = 0; + memcpy (b, input, sizeof (b)); #ifdef WORDS_BIGENDIAN - b[0] = byte_swap_32 (input[0]); - b[1] = byte_swap_32 (input[1]); - b[2] = byte_swap_32 (input[2]); - b[3] = byte_swap_32 (input[3]); -#else - b[0] = input[0]; - b[1] = input[1]; - b[2] = input[2]; - b[3] = input[3]; + b[0] = byte_swap_32 (b[0]); + b[1] = byte_swap_32 (b[1]); + b[2] = byte_swap_32 (b[2]); + b[3] = byte_swap_32 (b[3]); #endif ROUND (0, context->keys, b, b_next); @@ -759,35 +752,27 @@ serpent_encrypt_internal (serpent_context_t *context, ROUND_LAST (7, context->keys, b, b_next); #ifdef WORDS_BIGENDIAN - output[0] = byte_swap_32 (b_next[0]); - output[1] = byte_swap_32 (b_next[1]); - output[2] = byte_swap_32 (b_next[2]); - output[3] = byte_swap_32 (b_next[3]); -#else - output[0] = b_next[0]; - output[1] = b_next[1]; - output[2] = b_next[2]; - output[3] = b_next[3]; + b_next[0] = byte_swap_32 (b_next[0]); + b_next[1] = byte_swap_32 (b_next[1]); + b_next[2] = byte_swap_32 (b_next[2]); + b_next[3] = byte_swap_32 (b_next[3]); #endif + memcpy (output, b_next, sizeof (b_next)); } static void serpent_decrypt_internal (serpent_context_t *context, - const serpent_block_t input, serpent_block_t output) + const byte *input, byte *output) { serpent_block_t b, b_next; int round = ROUNDS; + memcpy (b, input, sizeof (b)); #ifdef WORDS_BIGENDIAN - b_next[0] = byte_swap_32 (input[0]); - b_next[1] = byte_swap_32 (input[1]); - b_next[2] = byte_swap_32 (input[2]); - b_next[3] = byte_swap_32 (input[3]); -#else - b_next[0] = input[0]; - b_next[1] = input[1]; - b_next[2] = input[2]; - b_next[3] = input[3]; + b[0] = byte_swap_32 (b[0]); + b[1] = byte_swap_32 (b[1]); + b[2] = byte_swap_32 (b[2]); + b[3] = byte_swap_32 (b[3]); #endif ROUND_FIRST_INVERSE (7, context->keys, b_next, b); @@ -824,18 +809,13 @@ serpent_decrypt_internal (serpent_context_t *context, ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); - #ifdef WORDS_BIGENDIAN - output[0] = byte_swap_32 (b_next[0]); - output[1] = byte_swap_32 (b_next[1]); - output[2] = byte_swap_32 (b_next[2]); - output[3] = byte_swap_32 (b_next[3]); -#else - output[0] = b_next[0]; - output[1] = b_next[1]; - output[2] = b_next[2]; - output[3] = b_next[3]; + b_next[0] = byte_swap_32 (b_next[0]); + b_next[1] = byte_swap_32 (b_next[1]); + b_next[2] = byte_swap_32 (b_next[2]); + b_next[3] = byte_swap_32 (b_next[3]); #endif + memcpy (output, b_next, sizeof (b_next)); } static void @@ -843,8 +823,7 @@ serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; - serpent_encrypt_internal (context, - (const u32 *) buffer_in, (u32 *) buffer_out); + serpent_encrypt_internal (context, buffer_in, buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } @@ -853,9 +832,7 @@ serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; - serpent_decrypt_internal (context, - (const u32 *) buffer_in, - (u32 *) buffer_out); + serpent_decrypt_internal (context, buffer_in, buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } @@ -915,8 +892,8 @@ serpent_test (void) serpent_setkey_internal (&context, test_data[i].key, test_data[i].key_length); serpent_encrypt_internal (&context, - (const u32 *) test_data[i].text_plain, - (u32 *) scratch); + test_data[i].text_plain, + scratch); if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) switch (test_data[i].key_length) @@ -930,8 +907,8 @@ serpent_test (void) } serpent_decrypt_internal (&context, - (const u32 *) test_data[i].text_cipher, - (u32 *) scratch); + test_data[i].text_cipher, + scratch); if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) switch (test_data[i].key_length) { From e5f4d2607a7e6933b4dea713a921de30dda6508c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:26:17 +0100 Subject: [PATCH 312/315] * grub-core/lib/libgcrypt/cipher/md4.c (transform) [WORDS_BIGENDIAN]: Add missing const attribute. * grub-core/lib/libgcrypt/cipher/md5.c (transform) [WORDS_BIGENDIAN]: Likewise. * grub-core/lib/libgcrypt/cipher/rmd160.c (transform) [WORDS_BIGENDIAN]: Likewise. --- ChangeLog | 9 +++++++++ grub-core/lib/libgcrypt/cipher/md4.c | 3 ++- grub-core/lib/libgcrypt/cipher/md5.c | 3 ++- grub-core/lib/libgcrypt/cipher/rmd160.c | 3 ++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f44d38ed..e3eee32c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-12-15 Vladimir Serbinenko + + * grub-core/lib/libgcrypt/cipher/md4.c (transform) [WORDS_BIGENDIAN]: + Add missing const attribute. + * grub-core/lib/libgcrypt/cipher/md5.c (transform) [WORDS_BIGENDIAN]: + Likewise. + * grub-core/lib/libgcrypt/cipher/rmd160.c (transform) [WORDS_BIGENDIAN]: + Likewise. + 2011-12-15 Vladimir Serbinenko * grub-core/lib/libgcrypt/cipher/serpent.c (serpent_key_prepare): Fix diff --git a/grub-core/lib/libgcrypt/cipher/md4.c b/grub-core/lib/libgcrypt/cipher/md4.c index 680cf87f5..aa180f0d4 100644 --- a/grub-core/lib/libgcrypt/cipher/md4.c +++ b/grub-core/lib/libgcrypt/cipher/md4.c @@ -101,7 +101,8 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data ) #ifdef WORDS_BIGENDIAN { int i; - byte *p2, *p1; + byte *p2; + const byte *p1; for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 ) { p2[3] = *p1++; diff --git a/grub-core/lib/libgcrypt/cipher/md5.c b/grub-core/lib/libgcrypt/cipher/md5.c index 899dce89a..3d3046df2 100644 --- a/grub-core/lib/libgcrypt/cipher/md5.c +++ b/grub-core/lib/libgcrypt/cipher/md5.c @@ -92,7 +92,8 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data ) #ifdef WORDS_BIGENDIAN { int i; - byte *p2, *p1; + byte *p2; + const byte *p1; for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) { p2[3] = *p1++; diff --git a/grub-core/lib/libgcrypt/cipher/rmd160.c b/grub-core/lib/libgcrypt/cipher/rmd160.c index 7805bf53b..73d533739 100644 --- a/grub-core/lib/libgcrypt/cipher/rmd160.c +++ b/grub-core/lib/libgcrypt/cipher/rmd160.c @@ -169,7 +169,8 @@ transform ( RMD160_CONTEXT *hd, const unsigned char *data ) u32 x[16]; { int i; - byte *p2, *p1; + byte *p2; + const byte *p1; for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) { p2[3] = *p1++; From 70ffcc93eeb714992b6e90b6b2ae3feeb7444006 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:29:30 +0100 Subject: [PATCH 313/315] * util/grub-mkimage.c (generate_image): Clean multiboot header to avoid confusing ipxe. --- ChangeLog | 5 +++++ util/grub-mkimage.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index e3eee32c4..d7c458d15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Clean multiboot header to avoid + confusing ipxe. + 2011-12-15 Vladimir Serbinenko * grub-core/lib/libgcrypt/cipher/md4.c (transform) [WORDS_BIGENDIAN]: diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index de43c4493..ca8047df6 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -971,6 +972,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { char *pxeboot_path, *pxeboot_img; size_t pxeboot_size; + grub_uint32_t *ptr; pxeboot_path = grub_util_get_path (dir, "pxeboot.img"); pxeboot_size = grub_util_get_image_size (pxeboot_path); @@ -979,6 +981,18 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_write_image (pxeboot_img, pxeboot_size, out); free (pxeboot_img); free (pxeboot_path); + + /* Remove Multiboot header to avoid confusing ipxe. */ + for (ptr = (grub_uint32_t *) core_img; + ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++) + if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC) + && grub_target_to_host32 (ptr[0]) + + grub_target_to_host32 (ptr[1]) + + grub_target_to_host32 (ptr[2]) == 0) + { + *ptr = 0; + break; + } } boot_path = grub_util_get_path (dir, "diskboot.img"); From ff6b18b6182cbb3a16094257b89acd6b607d32ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:32:02 +0100 Subject: [PATCH 314/315] * util/import_gcry.py: Don't add include camellia.h to camellia.c. It's already there. --- ChangeLog | 5 +++++ util/import_gcry.py | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7c458d15..d7523e116 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * util/import_gcry.py: Don't add include camellia.h to camellia.c. It's + already there. + 2011-12-15 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Clean multiboot header to avoid diff --git a/util/import_gcry.py b/util/import_gcry.py index ec34d16b5..ae9602db4 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -105,8 +105,6 @@ for cipher_file in cipher_files: fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") - if cipher_file == "camellia.c": - fw.write ("#include \"camellia.h\"\n") if cipher_file == "camellia.h": fw.write ("#include \n") fw.write ("void camellia_setup128(const unsigned char *key, grub_uint32_t *subkey);\n") From c17e546ccab4b56c01cae45e27fc55ae244f5a97 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Dec 2011 20:33:32 +0100 Subject: [PATCH 315/315] * util/import_gcry.py: Skip _gcry_rmd160_mixblock and serpent_test. We don't use them. --- ChangeLog | 5 +++++ util/import_gcry.py | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d7523e116..74aa2a60d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-12-15 Vladimir Serbinenko + + * util/import_gcry.py: Skip _gcry_rmd160_mixblock and serpent_test. We + don't use them. + 2011-12-15 Vladimir Serbinenko * util/import_gcry.py: Don't add include camellia.h to camellia.c. It's diff --git a/util/import_gcry.py b/util/import_gcry.py index ae9602db4..e55ffd97b 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -190,8 +190,10 @@ for cipher_file in cipher_files: if hold: hold = False # We're optimising for size. - if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info)", line) is None: + if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test)", line) is None: skip = True + if not re.match ("serpent_test", line) is None: + fw.write ("static const char *serpent_test (void) { return 0; }\n"); fname = re.match ("[a-zA-Z0-9_]*", line).group () chmsg = "(%s): Removed." % fname if nch: