[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFCv2 31/38] common/gzip: add function to read isize field



The gzip specification dictates that the last four bytes of a gzip
file will contain the modulo 2^32 of the original image size. Since
this is a function of gzip, relocate the logic under a gzip function.

Signed-off-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
---
 xen/arch/x86/bzimage.c   | 10 +++-------
 xen/common/gzip/gunzip.c | 12 ++++++++++++
 xen/include/xen/gunzip.h |  3 +++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/bzimage.c b/xen/arch/x86/bzimage.c
index 66f648f311e4..eaea64b9c014 100644
--- a/xen/arch/x86/bzimage.c
+++ b/xen/arch/x86/bzimage.c
@@ -8,11 +8,6 @@
 #include <xen/libelf.h>
 #include <asm/bzimage.h>
 
-static __init unsigned long output_length(void *image, unsigned long image_len)
-{
-    return *(uint32_t *)(image + image_len - 4);
-}
-
 struct __packed setup_header {
         uint8_t         _pad0[0x1f1];           /* skip uninteresting stuff */
         uint8_t         setup_sects;
@@ -91,7 +86,8 @@ unsigned long __init bzimage_headroom(void *image_start,
         return 0;
 
     orig_image_len = image_length;
-    headroom = output_length(image_start, image_length);
+    /* Linux build system mimics gzip isize field for bzip2/lzma algos */
+    headroom = gzip_isize(image_start, image_length);
     if (gzip_check(image_start, image_length))
     {
         headroom += headroom >> 12; /* Add 8 bytes for every 32K input block */
@@ -124,7 +120,7 @@ int __init bzimage_parse(void *image_base, void 
**image_start,
 
     BUG_ON(!(image_base < *image_start));
 
-    output_len = output_length(*image_start, orig_image_len);
+    output_len = gzip_isize(*image_start, orig_image_len);
 
     if ( (err = perform_gunzip(image_base, *image_start, orig_image_len)) > 0 )
         err = decompress(*image_start, orig_image_len, image_base);
diff --git a/xen/common/gzip/gunzip.c b/xen/common/gzip/gunzip.c
index 89f45d4050ba..0963fe7bbd17 100644
--- a/xen/common/gzip/gunzip.c
+++ b/xen/common/gzip/gunzip.c
@@ -3,6 +3,7 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/unaligned.h>
 
 #define WSIZE           0x80000000U
 
@@ -106,6 +107,17 @@ __init int gzip_check(char *image, unsigned long image_len)
     return (magic0 == 0x1f) && ((magic1 == 0x8b) || (magic1 == 0x9e));
 }
 
+/*
+ * RFC 1952 specifies the last four bytes as the isize field, the size of the
+ * original (uncompressed) input data modulo 2^32.
+ */
+__init uint32_t gzip_isize(char *image, unsigned long image_len)
+{
+    uint32_t *ptr = (uint32_t *)(image + image_len - 4);
+
+    return get_unaligned(ptr);
+}
+
 __init int perform_gunzip(char *output, char *image, unsigned long image_len)
 {
     struct gunzip_state *s;
diff --git a/xen/include/xen/gunzip.h b/xen/include/xen/gunzip.h
index 805833127aba..1b45350c195f 100644
--- a/xen/include/xen/gunzip.h
+++ b/xen/include/xen/gunzip.h
@@ -1,7 +1,10 @@
 #ifndef __XEN_GUNZIP_H
 #define __XEN_GUNZIP_H
 
+#include <xen/types.h>
+
 int gzip_check(char *image, unsigned long image_len);
+uint32_t gzip_isize(char *image, unsigned long image_len);
 int perform_gunzip(char *output, char *image, unsigned long image_len);
 
 #endif
-- 
2.30.2




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.