aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-07-17 17:14:09 -0700
committerH. Peter Anvin <hpa@zytor.com>2013-07-17 17:34:24 -0700
commitd59bc9bd3ea1a10bcace54ed2c4125f3dc1ef3f8 (patch)
tree42fd36231da83e3972c07a4e452af4004a28906a
parente6451bde4b7f2936acbdfd5c4e5817b6df687a7c (diff)
downloadsyslinux-d59bc9bd3ea1a10bcace54ed2c4125f3dc1ef3f8.tar.gz
syslinux-d59bc9bd3ea1a10bcace54ed2c4125f3dc1ef3f8.tar.xz
syslinux-d59bc9bd3ea1a10bcace54ed2c4125f3dc1ef3f8.zip
zonelist: allow syslinux_memmap_type() to demote SMT_FREE to SMT_TERMINAL
Allow syslinux_memmap_type() to report any combination of SMT_FREE and SMT_TERMINAL as SMT_TERMINAL. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/lib/syslinux/zonelist.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/com32/lib/syslinux/zonelist.c b/com32/lib/syslinux/zonelist.c
index a6de1d85..f869bc6f 100644
--- a/com32/lib/syslinux/zonelist.c
+++ b/com32/lib/syslinux/zonelist.c
@@ -156,7 +156,8 @@ int syslinux_add_memmap(struct syslinux_memmap **list,
/*
* Verify what type a certain memory region is. This function returns
- * SMT_ERROR if the memory region has multiple types.
+ * SMT_ERROR if the memory region has multiple types, except that
+ * SMT_FREE can be demoted to SMT_TERMINAL.
*/
enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list,
addr_t start, addr_t len)
@@ -168,10 +169,18 @@ enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list,
while (list->type != SMT_END) {
llast = list->next->start - 1;
if (list->start <= start) {
- if (llast >= last)
+ if (llast >= last) {
return list->type; /* Region has a well-defined type */
- else if (llast >= start)
- return SMT_ERROR; /* Crosses region boundary */
+ } else if (llast >= start) {
+ /* Crosses region boundary */
+ while (valid_terminal_type(list->type)) {
+ list = list->next;
+ llast = list->next->start - 1;
+ if (llast >= last)
+ return SMT_TERMINAL;
+ }
+ return SMT_ERROR;
+ }
}
list = list->next;
}
@@ -300,7 +309,9 @@ int syslinux_memmap_find(struct syslinux_memmap *mmap,
return 0;
type = syslinux_memmap_type(mmap, *base, size);
- if (type == SMT_FREE || type == SMT_TERMINAL)
+
+ /* This assumes SMT_TERMINAL is OK if we can get the exact address */
+ if (valid_terminal_type(type))
return 0;
if (!relocate) {