elf.c: correct the Multiboot checksum algorithms
authorH. Peter Anvin <hpa@zytor.com>
Thu, 27 May 2010 13:54:30 +0000 (06:54 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 27 May 2010 13:59:28 +0000 (06:59 -0700)
The Multiboot checksum *only* applies to the "magic" and "flags"
fields, even if other fields in the header are actually used.

Accordingly, open-code the checksum algorithm instead of looping;
looping over two fields is kind of pointless.

Note that since those are the only non-zero fields in the current
header, the existing algorithm does produce the correct result.  This
is therefore a cleanup/future-proofing patch and not a critical bug
fix.

Reported-by: Paul Bolle <pebolle@tiscali.nl>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
elf.c

diff --git a/elf.c b/elf.c
index b420fed..7981eab 100644 (file)
--- a/elf.c
+++ b/elf.c
@@ -289,8 +289,7 @@ int output_multiboot(struct segment *segs, addr_t entry, FILE *out)
 {
        struct segment mb_seg;
        struct multiboot_header mb_hdr;
-       uint32_t csum;
-       char *p;
+       uint32_t magic, flags, csum;
 
        segs = sort_segments(segs);
 
@@ -307,14 +306,14 @@ int output_multiboot(struct segment *segs, addr_t entry, FILE *out)
        segs = &mb_seg;
 
        /* Multiboot header */
+       magic   = MULTIBOOT_MAGIC;
+       flags   = MB_FLAG_PAGE;
+
        memset(&mb_hdr, 0, sizeof mb_hdr);
-       wrle32(MULTIBOOT_MAGIC,&mb_hdr.magic);
-       wrle32(MB_FLAG_PAGE, &mb_hdr.flags);
+       wrle32(magic, &mb_hdr.magic);
+       wrle32(flags, &mb_hdr.flags);
 
-       csum = 0;
-       for (p = (char *)&mb_hdr; p < (char *)(&mb_hdr+1); p += 4) {
-               csum += rdle32((const uint32_t *)p);
-       }
+       csum    = magic + flags;
        wrle32(-csum, &mb_hdr.checksum);
 
        /* Generate the ELF image */