From baaafd3d78ece9cc0c91b4b37a4f54424f397755 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 29 May 2009 15:10:27 -0700 Subject: Run Nindent on com32/lib/syslinux/movebits.c Automatically reformat com32/lib/syslinux/movebits.c using Nindent. Do this for all files except HDT, gPXE and externally maintained libraries (zlib, tinyjpeg, libpng). Signed-off-by: H. Peter Anvin --- com32/lib/syslinux/movebits.c | 1021 +++++++++++++++++++++-------------------- 1 file changed, 511 insertions(+), 510 deletions(-) diff --git a/com32/lib/syslinux/movebits.c b/com32/lib/syslinux/movebits.c index 0da3146b..bd5ce0e8 100644 --- a/com32/lib/syslinux/movebits.c +++ b/com32/lib/syslinux/movebits.c @@ -66,129 +66,128 @@ static jmp_buf new_movelist_bail; -static struct syslinux_movelist * -new_movelist(addr_t dst, addr_t src, addr_t len) +static struct syslinux_movelist *new_movelist(addr_t dst, addr_t src, + addr_t len) { - struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist)); + struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist)); - if ( !ml ) - longjmp(new_movelist_bail, 1); + if (!ml) + longjmp(new_movelist_bail, 1); - ml->dst = dst; - ml->src = src; - ml->len = len; - ml->next = NULL; + ml->dst = dst; + ml->src = src; + ml->len = len; + ml->next = NULL; - return ml; + return ml; } -static struct syslinux_movelist * -dup_movelist(struct syslinux_movelist *src) +static struct syslinux_movelist *dup_movelist(struct syslinux_movelist *src) { - struct syslinux_movelist *dst = NULL, **dstp = &dst, *ml; + struct syslinux_movelist *dst = NULL, **dstp = &dst, *ml; - while (src) { - ml = new_movelist(src->dst, src->src, src->len); - *dstp = ml; - dstp = &ml->next; - src = src->next; - } + while (src) { + ml = new_movelist(src->dst, src->src, src->len); + *dstp = ml; + dstp = &ml->next; + src = src->next; + } - return dst; + return dst; } static void add_freelist(struct syslinux_memmap **mmap, addr_t start, addr_t len, enum syslinux_memmap_types type) { - if (syslinux_add_memmap(mmap, start, len, type)) - longjmp(new_movelist_bail, 1); + if (syslinux_add_memmap(mmap, start, len, type)) + longjmp(new_movelist_bail, 1); } /* * Take a chunk, entirely confined in **parentptr, and split it off so that * it has its own structure. */ -static struct syslinux_movelist ** -split_movelist(addr_t start, addr_t len, struct syslinux_movelist **parentptr) +static struct syslinux_movelist **split_movelist(addr_t start, addr_t len, + struct syslinux_movelist + **parentptr) { - struct syslinux_movelist *m, *ml = *parentptr; + struct syslinux_movelist *m, *ml = *parentptr; - assert(start >= ml->src); - assert(start < ml->src+ml->len); + assert(start >= ml->src); + assert(start < ml->src + ml->len); - /* Split off the beginning */ - if ( start > ml->src ) { - addr_t l = start - ml->src; + /* Split off the beginning */ + if (start > ml->src) { + addr_t l = start - ml->src; - m = new_movelist(ml->dst+l, start, ml->len-l); - m->next = ml->next; - ml->len = l; - ml->next = m; + m = new_movelist(ml->dst + l, start, ml->len - l); + m->next = ml->next; + ml->len = l; + ml->next = m; - parentptr = &ml->next; - ml = m; /* Continue processing the new node */ - } + parentptr = &ml->next; + ml = m; /* Continue processing the new node */ + } - /* Split off the end */ - if ( ml->len > len ) { - addr_t l = ml->len - len; + /* Split off the end */ + if (ml->len > len) { + addr_t l = ml->len - len; - m = new_movelist(ml->dst+len, ml->src+len, l); - m->next = ml->next; - ml->len = len; - ml->next = m; - } + m = new_movelist(ml->dst + len, ml->src + len, l); + m->next = ml->next; + ml->len = len; + ml->next = m; + } - return parentptr; + return parentptr; } -static void -delete_movelist(struct syslinux_movelist **parentptr) +static void delete_movelist(struct syslinux_movelist **parentptr) { - struct syslinux_movelist *o = *parentptr; - *parentptr = o->next; - free(o); + struct syslinux_movelist *o = *parentptr; + *parentptr = o->next; + free(o); } -static void -free_movelist(struct syslinux_movelist **parentptr) +static void free_movelist(struct syslinux_movelist **parentptr) { - while (*parentptr) - delete_movelist(parentptr); + while (*parentptr) + delete_movelist(parentptr); } /* * Scan the freelist looking for a particular chunk of memory */ -static const struct syslinux_memmap * -is_free_zone(const struct syslinux_memmap *list, addr_t start, addr_t len) +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; - - 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) { - dprintf("F: 0x%08x bytes at 0x%08x\n", - list->next->start, list->start); - return list; /* It's free */ + dprintf("f: 0x%08x bytes at 0x%08x\n", len, start); + + addr_t last, llast; + + 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) { + 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) { + return NULL; /* Crosses region boundary */ + } } - return NULL; /* Not free */ - } else if (llast >= start) { - return NULL; /* Crosses region boundary */ - } + list = list->next; } - list = list->next; - } - return NULL; /* Internal error? */ + return NULL; /* Internal error? */ } /* @@ -196,30 +195,30 @@ is_free_zone(const struct syslinux_memmap *list, addr_t start, addr_t len) * can fit X bytes; returns the length of the block on success. */ static addr_t free_area(const struct syslinux_memmap *mmap, - addr_t len, addr_t *start) + addr_t len, addr_t * start) { - const struct syslinux_memmap *best = NULL; - const struct syslinux_memmap *s; - addr_t slen, best_len = -1; - - for (s = mmap; s->type != SMT_END; s = s->next) { - if (s->type != SMT_FREE) - continue; - slen = s->next->start - s->start; - if (slen >= len) { - if (!best || best_len > slen) { - best = s; - best_len = slen; - } + const struct syslinux_memmap *best = NULL; + const struct syslinux_memmap *s; + addr_t slen, best_len = -1; + + for (s = mmap; s->type != SMT_END; s = s->next) { + if (s->type != SMT_FREE) + continue; + slen = s->next->start - s->start; + if (slen >= len) { + if (!best || best_len > slen) { + best = s; + best_len = slen; + } + } + } + + if (best) { + *start = best->start; + return best_len; + } else { + return 0; } - } - - if (best) { - *start = best->start; - return best_len; - } else { - return 0; - } } /* @@ -228,7 +227,7 @@ static addr_t free_area(const struct syslinux_memmap *mmap, static void allocate_from(struct syslinux_memmap **mmap, addr_t start, addr_t len) { - syslinux_add_memmap(mmap, start, len, SMT_ALLOC); + syslinux_add_memmap(mmap, start, len, SMT_ALLOC); } /* @@ -239,86 +238,89 @@ allocate_from(struct syslinux_memmap **mmap, addr_t start, addr_t len) static void shuffle_dealias(struct syslinux_movelist **fraglist, struct syslinux_movelist **postcopy) { - struct syslinux_movelist *mp, **mpp, *mx, *np; - addr_t ps, pe, xs, xe, delta; - bool advance; + struct syslinux_movelist *mp, **mpp, *mx, *np; + addr_t ps, pe, xs, xe, delta; + bool advance; #if DEBUG - dprintf("Before alias resolution:\n"); - syslinux_dump_movelist(stdout, *fraglist); + dprintf("Before alias resolution:\n"); + syslinux_dump_movelist(stdout, *fraglist); #endif - *postcopy = NULL; - - /* - * Note: as written, this is an O(n^2) algorithm; by producing a list - * sorted by destination address we could reduce it to O(n log n). - */ - mpp = fraglist; - while ((mp = *mpp)) { - dprintf("mp -> (%#x,%#x,%#x)\n", mp->dst, mp->src, mp->len); - ps = mp->src; - pe = mp->src + mp->len - 1; - for (mx = *fraglist; mx != mp; mx = mx->next) { - dprintf("mx -> (%#x,%#x,%#x)\n", mx->dst, mx->src, mx->len); - /* - * If there is any overlap between mx and mp, mp should be - * modified and possibly split. - */ - xs = mx->src; - xe = mx->src + mx->len - 1; - - dprintf("?: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe); - - if (pe <= xs || ps >= xe) - continue; /* No overlap */ - - advance = false; - *mpp = mp->next; /* Remove from list */ - - if (pe > xe) { - delta = pe-xe; - np = new_movelist(mp->dst+mp->len-delta, mp->src+mp->len-delta, delta); - mp->len -= delta; pe = xe; - np->next = *mpp; - *mpp = np; - advance = true; - } - if (ps < xs) { - delta = xs-ps; - np = new_movelist(mp->dst, ps, delta); - mp->src += delta; ps = mp->src; - mp->dst += delta; - mp->len -= delta; - np->next = *mpp; - *mpp = np; - advance = true; - } - - assert(ps >= xs && pe <= xe); - - dprintf("Overlap: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe); - - mp->src = mx->dst + (ps-xs); - mp->next = *postcopy; - *postcopy = mp; - - mp = *mpp; - - if (!advance) - goto restart; + *postcopy = NULL; + + /* + * Note: as written, this is an O(n^2) algorithm; by producing a list + * sorted by destination address we could reduce it to O(n log n). + */ + mpp = fraglist; + while ((mp = *mpp)) { + dprintf("mp -> (%#x,%#x,%#x)\n", mp->dst, mp->src, mp->len); + ps = mp->src; + pe = mp->src + mp->len - 1; + for (mx = *fraglist; mx != mp; mx = mx->next) { + dprintf("mx -> (%#x,%#x,%#x)\n", mx->dst, mx->src, mx->len); + /* + * If there is any overlap between mx and mp, mp should be + * modified and possibly split. + */ + xs = mx->src; + xe = mx->src + mx->len - 1; + + dprintf("?: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe); + + if (pe <= xs || ps >= xe) + continue; /* No overlap */ + + advance = false; + *mpp = mp->next; /* Remove from list */ + + if (pe > xe) { + delta = pe - xe; + np = new_movelist(mp->dst + mp->len - delta, + mp->src + mp->len - delta, delta); + mp->len -= delta; + pe = xe; + np->next = *mpp; + *mpp = np; + advance = true; + } + if (ps < xs) { + delta = xs - ps; + np = new_movelist(mp->dst, ps, delta); + mp->src += delta; + ps = mp->src; + mp->dst += delta; + mp->len -= delta; + np->next = *mpp; + *mpp = np; + advance = true; + } + + assert(ps >= xs && pe <= xe); + + dprintf("Overlap: %#x..%#x (inside %#x..%#x)\n", ps, pe, xs, xe); + + mp->src = mx->dst + (ps - xs); + mp->next = *postcopy; + *postcopy = mp; + + mp = *mpp; + + if (!advance) + goto restart; + } + + mpp = &mp->next; +restart: + ; } - - mpp = &mp->next; - restart: - ; - } #if DEBUG - dprintf("After alias resolution:\n"); - syslinux_dump_movelist(stdout, *fraglist); - dprintf("Post-shuffle copies:\n"); - syslinux_dump_movelist(stdout, *postcopy); + dprintf("After alias resolution:\n"); + syslinux_dump_movelist(stdout, *fraglist); + dprintf("Post-shuffle copies:\n"); + syslinux_dump_movelist(stdout, *postcopy); #endif } @@ -330,67 +332,66 @@ move_chunk(struct syslinux_movelist ***moves, struct syslinux_memmap **mmap, struct syslinux_movelist **fp, addr_t copylen) { - addr_t copydst, copysrc; - addr_t freebase, freelen; - addr_t needlen; - int reverse; - struct syslinux_movelist *f = *fp, *mv; - - if ( f->src < f->dst && (f->dst - f->src) < f->len ) { - /* "Shift up" type overlap */ - needlen = f->dst - f->src; - reverse = 1; - } else if ( f->src > f->dst && (f->src - f->dst) < f->len ) { - /* "Shift down" type overlap */ - needlen = f->src - f->dst; - reverse = 0; - } else { - needlen = f->len; - reverse = 0; - } - - copydst = f->dst; - copysrc = f->src; - - dprintf("Q: copylen = 0x%08x, needlen = 0x%08x\n", copylen, needlen); - - if ( copylen < needlen ) { - if (reverse) { - copydst += (f->len-copylen); - copysrc += (f->len-copylen); + addr_t copydst, copysrc; + addr_t freebase, freelen; + addr_t needlen; + int reverse; + struct syslinux_movelist *f = *fp, *mv; + + if (f->src < f->dst && (f->dst - f->src) < f->len) { + /* "Shift up" type overlap */ + needlen = f->dst - f->src; + reverse = 1; + } else if (f->src > f->dst && (f->src - f->dst) < f->len) { + /* "Shift down" type overlap */ + needlen = f->src - f->dst; + reverse = 0; + } else { + needlen = f->len; + reverse = 0; + } + + copydst = f->dst; + copysrc = f->src; + + dprintf("Q: copylen = 0x%08x, needlen = 0x%08x\n", copylen, needlen); + + if (copylen < needlen) { + if (reverse) { + copydst += (f->len - copylen); + copysrc += (f->len - copylen); + } + + dprintf("X: 0x%08x bytes at 0x%08x -> 0x%08x\n", + copylen, copysrc, copydst); + + /* Didn't get all we wanted, so we have to split the chunk */ + fp = split_movelist(copysrc, copylen, fp); /* Is this right? */ + f = *fp; } - dprintf("X: 0x%08x bytes at 0x%08x -> 0x%08x\n", - copylen, copysrc, copydst); - - /* Didn't get all we wanted, so we have to split the chunk */ - fp = split_movelist(copysrc, copylen, fp); /* Is this right? */ - f = *fp; - } - - mv = new_movelist(f->dst, f->src, f->len); - dprintf("A: 0x%08x bytes at 0x%08x -> 0x%08x\n", - mv->len, mv->src, mv->dst); - **moves = mv; - *moves = &mv->next; - - /* Figure out what memory we just freed up */ - if ( f->dst > f->src ) { - freebase = f->src; - freelen = min(f->len, f->dst-f->src); - } else if ( f->src >= f->dst+f->len ) { - freebase = f->src; - freelen = f->len; - } else { - freelen = f->src-f->dst; - freebase = f->dst+f->len; - } - - dprintf("F: 0x%08x bytes at 0x%08x\n", freelen, freebase); - - add_freelist(mmap, freebase, freelen, SMT_FREE); - - delete_movelist(fp); + mv = new_movelist(f->dst, f->src, f->len); + dprintf("A: 0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst); + **moves = mv; + *moves = &mv->next; + + /* Figure out what memory we just freed up */ + if (f->dst > f->src) { + freebase = f->src; + freelen = min(f->len, f->dst - f->src); + } else if (f->src >= f->dst + f->len) { + freebase = f->src; + freelen = f->len; + } else { + freelen = f->src - f->dst; + freebase = f->dst + f->len; + } + + dprintf("F: 0x%08x bytes at 0x%08x\n", freelen, freebase); + + add_freelist(mmap, freebase, freelen, SMT_FREE); + + delete_movelist(fp); } /* @@ -402,255 +403,255 @@ syslinux_compute_movelist(struct syslinux_movelist **moves, struct syslinux_movelist *ifrags, struct syslinux_memmap *memmap) { - struct syslinux_memmap *mmap = NULL; - const struct syslinux_memmap *mm, *ep; - struct syslinux_movelist *frags = NULL; - struct syslinux_movelist *postcopy = NULL; - struct syslinux_movelist *mv; - struct syslinux_movelist *f, **fp; - struct syslinux_movelist *o, **op; - addr_t needbase, needlen, copysrc, copydst, copylen; - addr_t avail; - addr_t fstart, flen; - addr_t cbyte; - addr_t ep_len; - int rv = -1; - int reverse; - - dprintf("entering syslinux_compute_movelist()...\n"); - - if (setjmp(new_movelist_bail)) { - nomem: - dprintf("Out of working memory!\n"); - goto bail; - } - - *moves = NULL; - - /* Create our memory map. Anything that is SMT_FREE or SMT_ZERO is - fair game, but mark anything used by source material as SMT_ALLOC. */ - mmap = syslinux_init_memmap(); - if (!mmap) - goto nomem; - - frags = dup_movelist(ifrags); - - /* Process one-to-many conditions */ - shuffle_dealias(&frags, &postcopy); - - for (mm = memmap; mm->type != SMT_END; mm = mm->next) - add_freelist(&mmap, mm->start, mm->next->start - mm->start, - mm->type == SMT_ZERO ? SMT_FREE : mm->type); - - for (f = frags; f; f = f->next) - add_freelist(&mmap, f->src, f->len, SMT_ALLOC); - - /* As long as there are unprocessed fragments in the chain... */ - while ( (fp = &frags, f = *fp) ) { + struct syslinux_memmap *mmap = NULL; + const struct syslinux_memmap *mm, *ep; + struct syslinux_movelist *frags = NULL; + struct syslinux_movelist *postcopy = NULL; + struct syslinux_movelist *mv; + struct syslinux_movelist *f, **fp; + struct syslinux_movelist *o, **op; + addr_t needbase, needlen, copysrc, copydst, copylen; + addr_t avail; + addr_t fstart, flen; + addr_t cbyte; + addr_t ep_len; + int rv = -1; + int reverse; + + dprintf("entering syslinux_compute_movelist()...\n"); + + if (setjmp(new_movelist_bail)) { +nomem: + dprintf("Out of working memory!\n"); + goto bail; + } -#if DEBUG - dprintf("Current free list:\n"); - syslinux_dump_memmap(stdout, mmap); - dprintf("Current frag list:\n"); - syslinux_dump_movelist(stdout, frags); -#endif + *moves = NULL; - /* Scan for fragments which can be discarded without action. */ - if ( f->src == f->dst ) { - delete_movelist(fp); - continue; - } - op = &f->next; - while ( (o = *op) ) { - if ( o->src == o->dst ) - delete_movelist(op); - else - op = &o->next; - } + /* Create our memory map. Anything that is SMT_FREE or SMT_ZERO is + fair game, but mark anything used by source material as SMT_ALLOC. */ + mmap = syslinux_init_memmap(); + if (!mmap) + goto nomem; - /* Scan for fragments which can be immediately moved - to their final destination, if so handle them now */ - for ( op = fp; (o = *op); op = &o->next ) { - if ( o->src < o->dst && (o->dst - o->src) < o->len ) { - /* "Shift up" type overlap */ - needlen = o->dst - o->src; - needbase = o->dst + (o->len - needlen); - reverse = 1; - cbyte = o->dst + o->len - 1; - } else if ( o->src > o->dst && (o->src - o->dst) < o->len ) { - /* "Shift down" type overlap */ - needlen = o->src - o->dst; - needbase = o->dst; - reverse = 0; - cbyte = o->dst; /* "Critical byte" */ - } else { - needlen = o->len; - needbase = o->dst; - reverse = 0; - cbyte = o->dst; /* "Critical byte" */ - } + frags = dup_movelist(ifrags); - if (is_free_zone(mmap, needbase, needlen)) { - fp = op, f = o; - dprintf("!: 0x%08x bytes at 0x%08x -> 0x%08x\n", - f->len, f->src, f->dst); - copysrc = f->src; - copylen = needlen; - allocate_from(&mmap, needbase, copylen); - goto move_chunk; - } - } + /* Process one-to-many conditions */ + shuffle_dealias(&frags, &postcopy); - /* Ok, bother. Need to do real work at least with one chunk. */ - - dprintf("@: 0x%08x bytes at 0x%08x -> 0x%08x\n", - f->len, f->src, f->dst); - - /* See if we can move this chunk into place by claiming - the destination, or in the case of partial overlap, the - missing portion. */ - - if ( f->src < f->dst && (f->dst - f->src) < f->len ) { - /* "Shift up" type overlap */ - needlen = f->dst - f->src; - needbase = f->dst + (f->len - needlen); - reverse = 1; - cbyte = f->dst + f->len - 1; - } else if ( f->src > f->dst && (f->src - f->dst) < f->len ) { - /* "Shift down" type overlap */ - needlen = f->src - f->dst; - needbase = f->dst; - reverse = 0; - cbyte = f->dst; /* "Critical byte" */ - } else { - needlen = f->len; - needbase = f->dst; - reverse = 0; - cbyte = f->dst; - } + for (mm = memmap; mm->type != SMT_END; mm = mm->next) + add_freelist(&mmap, mm->start, mm->next->start - mm->start, + mm->type == SMT_ZERO ? SMT_FREE : mm->type); - dprintf("need: base = 0x%08x, len = 0x%08x, " - "reverse = %d, cbyte = 0x%08x\n", - needbase, needlen, reverse, cbyte); - - ep = is_free_zone(mmap, cbyte, 1); - if (ep) { - ep_len = ep->next->start - ep->start; - if (reverse) - avail = needbase+needlen - ep->start; - else - avail = ep_len - (needbase - ep->start); - } else { - avail = 0; - } + for (f = frags; f; f = f->next) + add_freelist(&mmap, f->src, f->len, SMT_ALLOC); - if (avail) { - /* We can move at least part of this chunk into place without - further ado */ - dprintf("space: start 0x%08x, len 0x%08x, free 0x%08x\n", - ep->start, ep_len, avail); - copylen = min(needlen, avail); + /* As long as there are unprocessed fragments in the chain... */ + while ((fp = &frags, f = *fp)) { - if (reverse) - allocate_from(&mmap, needbase+needlen-copylen, copylen); - else - allocate_from(&mmap, needbase, copylen); +#if DEBUG + dprintf("Current free list:\n"); + syslinux_dump_memmap(stdout, mmap); + dprintf("Current frag list:\n"); + syslinux_dump_movelist(stdout, frags); +#endif - goto move_chunk; - } + /* Scan for fragments which can be discarded without action. */ + if (f->src == f->dst) { + delete_movelist(fp); + continue; + } + op = &f->next; + while ((o = *op)) { + if (o->src == o->dst) + delete_movelist(op); + else + op = &o->next; + } - /* At this point, we need to evict something out of our space. - Find the object occupying the critical byte of our target space, - and move it out (the whole object if we can, otherwise a subset.) - Then move a chunk of ourselves into place. */ - for ( op = &f->next, o = *op ; o ; op = &o->next, o = *op ) { - - dprintf("O: 0x%08x bytes at 0x%08x -> 0x%08x\n", - o->len, o->src, o->dst); - - if ( !(o->src <= cbyte && o->src+o->len > cbyte) ) - continue; /* Not what we're looking for... */ - - /* Find somewhere to put it... */ - - if ( is_free_zone(mmap, o->dst, o->len) ) { - /* Score! We can move it into place directly... */ - copydst = o->dst; - copysrc = o->src; - copylen = o->len; - } else if ( free_area(mmap, o->len, &fstart) ) { - /* We can move the whole chunk */ - copydst = fstart; - copysrc = o->src; - copylen = o->len; - } else { - /* Well, copy as much as we can... */ - if (syslinux_memmap_largest(mmap, SMT_FREE, &fstart, &flen)) { - dprintf("No free memory at all!\n"); - goto bail; /* Stuck! */ + /* Scan for fragments which can be immediately moved + to their final destination, if so handle them now */ + for (op = fp; (o = *op); op = &o->next) { + if (o->src < o->dst && (o->dst - o->src) < o->len) { + /* "Shift up" type overlap */ + needlen = o->dst - o->src; + needbase = o->dst + (o->len - needlen); + reverse = 1; + cbyte = o->dst + o->len - 1; + } else if (o->src > o->dst && (o->src - o->dst) < o->len) { + /* "Shift down" type overlap */ + needlen = o->src - o->dst; + needbase = o->dst; + reverse = 0; + cbyte = o->dst; /* "Critical byte" */ + } else { + needlen = o->len; + needbase = o->dst; + reverse = 0; + cbyte = o->dst; /* "Critical byte" */ + } + + if (is_free_zone(mmap, needbase, needlen)) { + fp = op, f = o; + dprintf("!: 0x%08x bytes at 0x%08x -> 0x%08x\n", + f->len, f->src, f->dst); + copysrc = f->src; + copylen = needlen; + allocate_from(&mmap, needbase, copylen); + goto move_chunk; + } } - /* Make sure we include the critical byte */ - copydst = fstart; - if (reverse) { - copysrc = max(o->src, cbyte+1 - flen); - copylen = cbyte+1 - copysrc; + /* Ok, bother. Need to do real work at least with one chunk. */ + + dprintf("@: 0x%08x bytes at 0x%08x -> 0x%08x\n", + f->len, f->src, f->dst); + + /* See if we can move this chunk into place by claiming + the destination, or in the case of partial overlap, the + missing portion. */ + + if (f->src < f->dst && (f->dst - f->src) < f->len) { + /* "Shift up" type overlap */ + needlen = f->dst - f->src; + needbase = f->dst + (f->len - needlen); + reverse = 1; + cbyte = f->dst + f->len - 1; + } else if (f->src > f->dst && (f->src - f->dst) < f->len) { + /* "Shift down" type overlap */ + needlen = f->src - f->dst; + needbase = f->dst; + reverse = 0; + cbyte = f->dst; /* "Critical byte" */ + } else { + needlen = f->len; + needbase = f->dst; + reverse = 0; + cbyte = f->dst; + } + + dprintf("need: base = 0x%08x, len = 0x%08x, " + "reverse = %d, cbyte = 0x%08x\n", + needbase, needlen, reverse, cbyte); + + ep = is_free_zone(mmap, cbyte, 1); + if (ep) { + ep_len = ep->next->start - ep->start; + if (reverse) + avail = needbase + needlen - ep->start; + else + avail = ep_len - (needbase - ep->start); } else { - copysrc = cbyte; - copylen = min(flen, o->len - (cbyte-o->src)); + avail = 0; } - } - allocate_from(&mmap, copydst, copylen); - - if ( copylen < o->len ) { - op = split_movelist(copysrc, copylen, op); - o = *op; - } - - mv = new_movelist(copydst, copysrc, copylen); - dprintf("C: 0x%08x bytes at 0x%08x -> 0x%08x\n", - mv->len, mv->src, mv->dst); - *moves = mv; - moves = &mv->next; - - o->src = copydst; - - if ( copylen > needlen ) { - /* We don't need all the memory we freed up. Mark it free. */ - if ( copysrc < needbase ) { - add_freelist(&mmap, copysrc, needbase-copysrc, SMT_FREE); - copylen -= (needbase-copysrc); + + if (avail) { + /* We can move at least part of this chunk into place without + further ado */ + dprintf("space: start 0x%08x, len 0x%08x, free 0x%08x\n", + ep->start, ep_len, avail); + copylen = min(needlen, avail); + + if (reverse) + allocate_from(&mmap, needbase + needlen - copylen, copylen); + else + allocate_from(&mmap, needbase, copylen); + + goto move_chunk; } - if ( copylen > needlen ) { - add_freelist(&mmap, copysrc+needlen, copylen-needlen, SMT_FREE); - copylen = needlen; + + /* At this point, we need to evict something out of our space. + Find the object occupying the critical byte of our target space, + and move it out (the whole object if we can, otherwise a subset.) + Then move a chunk of ourselves into place. */ + for (op = &f->next, o = *op; o; op = &o->next, o = *op) { + + dprintf("O: 0x%08x bytes at 0x%08x -> 0x%08x\n", + o->len, o->src, o->dst); + + if (!(o->src <= cbyte && o->src + o->len > cbyte)) + continue; /* Not what we're looking for... */ + + /* Find somewhere to put it... */ + + if (is_free_zone(mmap, o->dst, o->len)) { + /* Score! We can move it into place directly... */ + copydst = o->dst; + copysrc = o->src; + copylen = o->len; + } else if (free_area(mmap, o->len, &fstart)) { + /* We can move the whole chunk */ + copydst = fstart; + copysrc = o->src; + copylen = o->len; + } else { + /* Well, copy as much as we can... */ + if (syslinux_memmap_largest(mmap, SMT_FREE, &fstart, &flen)) { + dprintf("No free memory at all!\n"); + goto bail; /* Stuck! */ + } + + /* Make sure we include the critical byte */ + copydst = fstart; + if (reverse) { + copysrc = max(o->src, cbyte + 1 - flen); + copylen = cbyte + 1 - copysrc; + } else { + copysrc = cbyte; + copylen = min(flen, o->len - (cbyte - o->src)); + } + } + allocate_from(&mmap, copydst, copylen); + + if (copylen < o->len) { + op = split_movelist(copysrc, copylen, op); + o = *op; + } + + mv = new_movelist(copydst, copysrc, copylen); + dprintf("C: 0x%08x bytes at 0x%08x -> 0x%08x\n", + mv->len, mv->src, mv->dst); + *moves = mv; + moves = &mv->next; + + o->src = copydst; + + if (copylen > needlen) { + /* We don't need all the memory we freed up. Mark it free. */ + if (copysrc < needbase) { + add_freelist(&mmap, copysrc, needbase - copysrc, SMT_FREE); + copylen -= (needbase - copysrc); + } + if (copylen > needlen) { + add_freelist(&mmap, copysrc + needlen, copylen - needlen, + SMT_FREE); + copylen = needlen; + } + } + reverse = 0; + goto move_chunk; } - } - reverse = 0; - goto move_chunk; + dprintf("Cannot find the chunk containing the critical byte\n"); + goto bail; /* Stuck! */ + +move_chunk: + move_chunk(&moves, &mmap, fp, copylen); } - dprintf("Cannot find the chunk containing the critical byte\n"); - goto bail; /* Stuck! */ - - move_chunk: - move_chunk(&moves, &mmap, fp, copylen); - } - - /* Finally, append the postcopy chain to the end of the moves list */ - for (op = moves; (o = *op); op = &o->next) - ; /* Locate the end of the list */ - *op = postcopy; - postcopy = NULL; - - rv = 0; - bail: - if (mmap) - syslinux_free_memmap(mmap); - if (frags) - free_movelist(&frags); - if (postcopy) - free_movelist(&postcopy); - return rv; + + /* Finally, append the postcopy chain to the end of the moves list */ + for (op = moves; (o = *op); op = &o->next) ; /* Locate the end of the list */ + *op = postcopy; + postcopy = NULL; + + rv = 0; +bail: + if (mmap) + syslinux_free_memmap(mmap); + if (frags) + free_movelist(&frags); + if (postcopy) + free_movelist(&postcopy); + return rv; } #ifdef TEST @@ -659,51 +660,51 @@ syslinux_compute_movelist(struct syslinux_movelist **moves, int main(int argc, char *argv[]) { - FILE *f; - unsigned long d, s, l; - struct syslinux_movelist *frags; - struct syslinux_movelist **fep = &frags; - struct syslinux_movelist *mv, *moves; - struct syslinux_memmap *memmap; - char line[BUFSIZ]; - - (void)argc; - - memmap = syslinux_init_memmap(); - - f = fopen(argv[1], "r"); - while ( fgets(line, sizeof line, f) != NULL ) { - if ( sscanf(line, "%lx %lx %lx", &s, &d, &l) == 3 ) { - if ( d ) { - if (s == -1UL) { - syslinux_add_memmap(&memmap, d, l, SMT_ZERO); - } else { - mv = new_movelist(d, s, l); - *fep = mv; - fep = &mv->next; + FILE *f; + unsigned long d, s, l; + struct syslinux_movelist *frags; + struct syslinux_movelist **fep = &frags; + struct syslinux_movelist *mv, *moves; + struct syslinux_memmap *memmap; + char line[BUFSIZ]; + + (void)argc; + + memmap = syslinux_init_memmap(); + + f = fopen(argv[1], "r"); + while (fgets(line, sizeof line, f) != NULL) { + if (sscanf(line, "%lx %lx %lx", &s, &d, &l) == 3) { + if (d) { + if (s == -1UL) { + syslinux_add_memmap(&memmap, d, l, SMT_ZERO); + } else { + mv = new_movelist(d, s, l); + *fep = mv; + fep = &mv->next; + } + } else { + syslinux_add_memmap(&memmap, s, l, SMT_FREE); + } } - } else { - syslinux_add_memmap(&memmap, s, l, SMT_FREE); - } } - } - fclose(f); - - *fep = NULL; - - printf("Input move list:\n"); - syslinux_dump_movelist(stdout, frags); - printf("Input free list:\n"); - syslinux_dump_memmap(stdout, memmap); - - if ( syslinux_compute_movelist(&moves, frags, memmap) ) { - printf("Failed to compute a move sequence\n"); - return 1; - } else { - printf("Final move list:\n"); - syslinux_dump_movelist(stdout, moves); - return 0; - } - } + fclose(f); + + *fep = NULL; + + printf("Input move list:\n"); + syslinux_dump_movelist(stdout, frags); + printf("Input free list:\n"); + syslinux_dump_memmap(stdout, memmap); + + if (syslinux_compute_movelist(&moves, frags, memmap)) { + printf("Failed to compute a move sequence\n"); + return 1; + } else { + printf("Final move list:\n"); + syslinux_dump_movelist(stdout, moves); + return 0; + } +} #endif /* TEST */ -- cgit v1.2.1