Some changes to handle more on small machines:
authorceriel <none@none>
Thu, 21 May 1987 10:06:14 +0000 (10:06 +0000)
committerceriel <none@none>
Thu, 21 May 1987 10:06:14 +0000 (10:06 +0000)
a section is now split into parts that fit in core

util/led/finish.c
util/led/mach.c
util/led/memory.c
util/led/relocate.c
util/led/scan.c

index 19120c6..12daa31 100644 (file)
@@ -100,18 +100,21 @@ handle_relos(head, sects, names)
                                sectindex = relo->or_sect - S_MIN;
                                emit = getemit(head, sects, sectindex);
                        }
-                       relocate(head, emit, names, relo);
+                       relocate(head, emit, names, relo, 0L);
                        relo++;
                }
        } else {
                for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) {
                        if (sects[sectindex].os_flen) {
+                               wrt_nulls(sectindex, zeros[sectindex]);
+                               zeros[sectindex] = 0;
                                emit = getemit(head, sects, sectindex);
-                               nrelo = head->oh_nrelo; startrelo(head);
-                               while (nrelo--) {
+                               if (emit) {
+                                   nrelo = head->oh_nrelo; startrelo(head);
+                                   while (nrelo--) {
                                        relo = nextrelo();
                                        if (relo->or_sect - S_MIN == sectindex) {
-                                               relocate(head,emit,names,relo);
+                                               relocate(head,emit,names,relo,0L);
                                                /*
                                                 * Write out the (probably changed)
                                                 * relocation information.
@@ -119,16 +122,48 @@ handle_relos(head, sects, names)
                                                if (flagword & RFLAG)
                                                        wr_relo(relo, 1);
                                        }
+                                   }
+                                   wrt_emit(emit, sectindex,
+                                       sects[sectindex].os_flen);
                                }
-                               wrt_nulls(sectindex, zeros[sectindex]);
-                               zeros[sectindex] = 0;
-                               wrt_emit(emit, sectindex, sects[sectindex].os_flen);
+                               else {
+                                   long sz = sects[sectindex].os_flen;
+                                   long sf = 0;
+                                   long blksz;
+                                   char *getblk();
+
+                                   emit = getblk(sz, &blksz, sectindex);
+                                   while (sz) {
+                                       long sz2 = sz > blksz ? blksz : sz;
+
+                                       rd_emit(emit, sz2);
+                                       nrelo = head->oh_nrelo; startrelo(head);
+                                       while (nrelo--) {
+                                           relo = nextrelo();
+                                           if (relo->or_sect-S_MIN==sectindex
+                                               &&
+                                               relo->or_addr >= sf
+                                               &&
+                                               relo->or_addr < sf + sz2){
+                                               relocate(head,emit,names,relo,
+                                                        sf);
+                                               /*
+                                                * Write out the (probably changed)
+                                                * relocation information.
+                                                */
+                                               if (flagword & RFLAG)
+                                                       wr_relo(relo, 1);
+                                           }
+                                       }
+                                       wrt_emit(emit, sectindex, sz2);
+                                       sz -= sz2;
+                                       sf += sz2;
+                                   }
+                               }
+                               endemit(emit);
                        }
                        zeros[sectindex] += sects[sectindex].os_size -
                                            sects[sectindex].os_flen;
-                       /*
-                        * XXX We should be able to free the emitted bytes.
-                        */
                }
        }
 }
index c61cd84..b1fe0d3 100644 (file)
@@ -31,6 +31,8 @@
        mems[ALLOMODL].mem_left = 32 * K;
        mems[ALLORANL].mem_left = 4 * K;
 #else
+#undef INCRSIZE
+#define INCRSIZE 256
        mems[ALLOEMIT + 0].mem_left = 8 * K;
        mems[ALLOEMIT + 1].mem_left = 2 * K;
        mems[ALLOEMIT + 2].mem_left = 4 * K;
index 4be4da5..781c162 100644 (file)
@@ -56,7 +56,8 @@ sbreak(incr)
            inc != incr ||
            BASE + inc < BASE ||
            (int) brk(BASE + inc) == -1) {
-               refused = refused && refused > incr ? incr : refused;
+               if (!refused || refused > incr)
+                       refused = incr;
                return -1;
        }
        BASE = sbrk(0);
@@ -133,10 +134,10 @@ init_core()
 
 /*
  * Allocate an extra block of `incr' bytes and move all pieces with index
- * higher than `piece' up with the size of the block. Return whether the
- * allocate succeeded.
+ * higher than `piece' up with the size of the block.
+ * Move up as much as possible, if "incr" fails.
  */
-static bool
+static ind_t
 move_up(piece, incr)
        register int            piece;
        register ind_t          incr;
@@ -144,14 +145,18 @@ move_up(piece, incr)
        register struct memory  *mem;
 
        debug("move_up(%d, %d)\n", piece, (int)incr, 0, 0);
-       if (sbreak(incr) == -1)
-               return FALSE;
+       while (incr > 0 && sbreak(incr) == -1)
+               incr -= INCRSIZE;
 
+       if (incr <= 0) {
+               incr = 0;
+               return (ind_t) 0;
+       }
        for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--)
                copy_up(mem, incr);
 
        mems[piece].mem_left += incr;
-       return TRUE;
+       return incr;
 }
 
 extern int     passnumber;
@@ -368,12 +373,12 @@ alloc(piece, size)
        if (size != (ind_t)size)
                return BADOFF;
 
-       while (left + incr < size)
-               incr += INCRSIZE;
-       
+       if (size - left > 0)
+               incr = ((size - left + (INCRSIZE - 1)) / INCRSIZE) * INCRSIZE;
+
        if (incr == 0 ||
-           (incr < left + full && move_up(piece, left + full)) ||
-           move_up(piece, incr) ||
+           (incr < left + full && (incr -= move_up(piece, left + full)) <= 0) ||
+           move_up(piece, incr) == incr ||
            compact(piece, size, alloctype)) {
                mems[piece].mem_full += size;
                mems[piece].mem_left -= size;
@@ -477,11 +482,29 @@ core_alloc(piece, size)
 {
        register ind_t  off;
 
-       if ((off = alloc(piece, size)) == BADOFF)
-               return (char *)0;
+       if ((off = alloc(piece, size)) == BADOFF) {
+               int sv = alloctype;
+
+               alloctype = FORCED;
+               off = alloc(piece, size);
+               alloctype = sv;
+               if (off == BADOFF)
+                       return (char *)0;
+       }
        return address(piece, off);
 }
 
+core_free(piece, p)
+       int     piece;
+       char    *p;
+{
+       char    *q = address(piece, mems[piece].mem_full);
+
+       assert(p < q);
+       mems[piece].mem_full -= ((ind_t)q - (ind_t)p);
+       mems[piece].mem_left += ((ind_t)q - (ind_t)p);
+}
+
 /*
  * Reset index into piece of memory for modules and
  * take care that the allocated pieces will not be moved.
index 5233268..9595e7f 100644 (file)
@@ -160,11 +160,12 @@ addrelo(relo, names, valu_out)
  * which the header is pointed to by `head'. Relocation is relative to the
  * names in `names'; `relo' tells how to relocate.
  */
-relocate(head, emit, names, relo)
+relocate(head, emit, names, relo, off)
        struct outhead  *head;
        char            *emit;
        struct outname  names[];
        struct outrelo  *relo;
+       long            off;
 {
        long            valu;
        int             sectindex = relo->or_sect - S_MIN;
@@ -173,7 +174,7 @@ relocate(head, emit, names, relo)
        /*
         * Pick up previous value at location to be relocated.
         */
-       valu = getvalu(emit + relo->or_addr, relo->or_type);
+       valu = getvalu(emit + (relo->or_addr - off), relo->or_type);
        /*
         * Or_nami is an index in the name table of the considered module.
         * The name of which it is an index can be:
@@ -204,7 +205,7 @@ relocate(head, emit, names, relo)
        /*
         * Now put the value back.
         */
-       putvalu(valu, emit + relo->or_addr, relo->or_type);
+       putvalu(valu, emit + (relo->or_addr - off), relo->or_type);
 
        /*
         * We must change the offset within the section of the value to be
index cfca314..362e0eb 100644 (file)
@@ -556,7 +556,7 @@ getemit(head, sects, sectindex)
        if (!incore) {
                ret = core_alloc(ALLOMODL, sects[sectindex].os_flen);
                if (ret == (char *)0)
-                       fatal("no space for section contents");
+                       return 0;
                rd_outsect(sectindex);
                rd_emit(ret, sects[sectindex].os_flen);
                return ret;
@@ -568,3 +568,34 @@ getemit(head, sects, sectindex)
        off = *((ind_t *)(modulbase + IND_EMIT(*head)) + sectindex);
        return address(ALLOEMIT + sectindex, off);
 }
+
+char *
+getblk(totalsz, pblksz, sectindex)
+       long    totalsz;
+       long    *pblksz;
+       int     sectindex;
+{
+       char    *ret;
+       long    sz = (1L << 30);
+
+       assert(!incore);
+
+       while (sz >= totalsz) sz >>= 1;
+       while (sz) {
+               ret = core_alloc(ALLOMODL, sz);
+               if (ret != (char *) 0) {
+                       rd_outsect(sectindex);
+                       *pblksz = sz;
+                       return ret;
+               }
+               sz >>= 1;
+       }
+       fatal("no space for section contents");
+       return (char *) 0;
+}
+
+endemit(emit)
+       char    *emit;
+{
+       core_free(ALLOMODL, emit);
+}