diff options
author | H. Peter Anvin <hpa@zytor.com> | 2013-07-17 17:21:42 -0700 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-07-18 11:37:49 +0100 |
commit | 65b7d4306aac6b81743df93fe23f6e24d64025f3 (patch) | |
tree | a9040e529c3f763dc9e860a2d2901586876e796f | |
parent | d59bc9bd3ea1a10bcace54ed2c4125f3dc1ef3f8 (diff) | |
download | syslinux-65b7d4306aac6b81743df93fe23f6e24d64025f3.tar.gz syslinux-65b7d4306aac6b81743df93fe23f6e24d64025f3.tar.xz syslinux-65b7d4306aac6b81743df93fe23f6e24d64025f3.zip |
movebits: Handle arbitrary combinations of SMT_FREE and SMT_TERMINALsyslinux-6.02-pre6
In theory we may have multiple subregions with SMT_FREE and
SMT_TERMINAL. This can be fairly easily integrated into a small loop.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | com32/lib/syslinux/movebits.c | 42 |
1 files changed, 13 insertions, 29 deletions
diff --git a/com32/lib/syslinux/movebits.c b/com32/lib/syslinux/movebits.c index 85852e75..63554012 100644 --- a/com32/lib/syslinux/movebits.c +++ b/com32/lib/syslinux/movebits.c @@ -142,48 +142,32 @@ static void free_movelist(struct syslinux_movelist **parentptr) delete_movelist(parentptr); } -static bool valid_type_combination(enum syslinux_memmap_types type1, - enum syslinux_memmap_types type2) -{ - if (type1 != SMT_FREE && type1 != SMT_TERMINAL) - return false; - - if (type2 != SMT_FREE && type2 != SMT_TERMINAL) - return false; - - return true; -} - /* - * Scan the freelist looking for a particular chunk of memory + * Scan the freelist looking for a particular chunk of memory. Returns + * the memmap chunk containing to the first byte of the region. */ static const struct syslinux_memmap *is_free_zone(const struct syslinux_memmap *list, addr_t start, addr_t len) { - dprintf("f: 0x%08x bytes at 0x%08x\n", len, start); - addr_t last, llast; + dprintf("f: 0x%08x bytes at 0x%08x\n", len, start); + last = start + len - 1; while (list->type != SMT_END) { - llast = list->next->start - 1; if (list->start <= start) { - if (llast >= last) { - /* Chunk has a single, well-defined type */ - if (list->type == SMT_FREE || list->type == SMT_TERMINAL) { - dprintf("F: 0x%08x bytes at 0x%08x\n", - list->next->start, list->start); - return list; /* It's free */ - } - return NULL; /* Not free */ - } else if (llast >= start) { - if (valid_type_combination(list->type, list->next->type)) - return list; - - return NULL; /* Crosses incompatible region boundary */ + const struct syslinux_memmap *ilist = list; + while (valid_terminal_type(list->type)) { + llast = list->next->start - 1; + if (llast >= last) + return ilist; + list = list->next; } + + if (list->start > start) + return NULL; /* Invalid type in region */ } list = list->next; } |