home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 November / PCO_1198.ISO / filesbbs / os2 / fn127os2.arj / FN127OS2.ZIP / fn127os2 / src / os2page.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-25  |  8.7 KB  |  327 lines

  1. /*
  2.  # $Id: os2page.c,v 1.2 1998/04/10 10:26:06 fbm Exp fbm $
  3.  # Copyright (C) 1997,1998 Farrell McKay
  4.  # All rights reserved.
  5.  #
  6.  # This file is part of the Fortify distribution, a toolkit for
  7.  # upgrading the cryptographic strength of the Netscape Navigator
  8.  # web browser, authored by Farrell McKay.
  9.  #
  10.  # This toolkit is provided to the recipient under the
  11.  # following terms and conditions:-
  12.  #   1.  This copyright notice must not be removed or modified.
  13.  #   2.  This toolkit may not be reproduced or included in any commercial
  14.  #       media distribution, or commercial publication (for example CD-ROM,
  15.  #       disk, book, magazine, journal) without first obtaining the author's
  16.  #       express permission.
  17.  #   3.  This toolkit, or any component of this toolkit, may not be
  18.  #       commercially resold, redeveloped, rewritten, enhanced or otherwise
  19.  #       used as the basis for commercial venture, without first obtaining
  20.  #       the author's express permission.
  21.  #   4.  Subject to the above conditions being observed (1-3), this toolkit
  22.  #       may be freely reproduced or redistributed.
  23.  #   5.  This software is provided "as-is", without express or implied
  24.  #       warranty.  In no event shall the author be liable for any direct,
  25.  #       indirect or consequential damages however caused.
  26.  #   6.  Subject to the above conditions being observed (1-5),
  27.  #       this toolkit may be used at no cost to the recipient.
  28.  #
  29.  # Farrell McKay
  30.  # Wayfarer Systems Pty Ltd        contact@fortify.net
  31.  */
  32.  
  33. #include <fcntl.h>
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <unistd.h>
  37. #include <memory.h>
  38.  
  39. #include "misc.h"
  40. #include "os2lx.h"
  41. #include "os2page.h"
  42. #include "trace.h"
  43.  
  44.  
  45. static lxPage_t *
  46. lxPages_new
  47. (
  48.     unsigned long        _rawOffset,
  49.     unsigned short        _rawSz,
  50.     unsigned short        _rawFlags,
  51.     unsigned long        _fileOffset
  52. )
  53. {
  54.     lxPage_t        *p;
  55.  
  56.     p = (lxPage_t *) _calloc(1, sizeof(lxPage_t));
  57.     p->rawOffset = _rawOffset;
  58.     p->rawSz = p->size = _rawSz;
  59.     p->rawFlags = p->flags = _rawFlags;
  60.     p->fileOffset = _fileOffset;
  61.  
  62.     return p;
  63. }
  64.  
  65. int
  66. lxPages_uncompressed(lxfile_t *lx, int pageNum)
  67. {
  68.     if (pageNum < 0 || pageNum >= lx->npages)
  69.         return -1;
  70.  
  71.     return (lx->pages[pageNum]->rawFlags == PAGE_PHYS)? 1: 0;
  72. }
  73.  
  74. #if 0
  75. /*
  76.  * This function decompresses a block of Lempel-Ziv compressed data.
  77.  */
  78. static int
  79. lz_expand(unsigned char *in, int size, unsigned char *out, int outsize)
  80. {
  81.                 // returns 0 - output buffer overflow!
  82.   int outleft = outsize;
  83.   while ( size > 0 && outleft > 0 ) {
  84.     unsigned char f = *in++;
  85.     unsigned int plain;
  86.     unsigned int backnum;
  87.     unsigned int backoff;
  88.     size--;
  89.     switch ( f & 3 ) {
  90.       case 0:
  91.         plain = f >> 2;
  92.     if ( plain != 0 ) {
  93. //00XXXXXX
  94.       if ( plain > outleft ) plain = outleft;
  95.       memcpy(out,in,plain);
  96.       out += plain;
  97.       outleft -= plain;
  98.       in  += plain;
  99.       size -= plain;
  100.     } else {
  101. //00000000:XXXXXXXX:YYYYYYYY
  102.       unsigned char byte;
  103.       plain = *in++;            // number of repeatings.
  104.       size--;
  105. //00000000:00000000
  106.       if ( plain == 0 ) break;
  107.       byte = *in++;
  108.       size--;
  109.       if ( plain > outleft ) plain = outleft;
  110.       memset(out,byte,plain);
  111.       out += plain;
  112.       outleft -= plain;
  113.     }
  114.         continue;
  115.       case 1:
  116. //10XXYYYZ:ZZZZZZZZ
  117.     plain   = (f >> 2) & 3;
  118.     backnum = ((f >> 4) & 7) + 3;
  119.     backoff = (*in++ << 1) + (f >> 7);
  120.     size--;
  121. fullCopy:
  122.     if ( plain > outleft ) plain = outleft;
  123.     memcpy(out,in,plain);
  124.     size -= plain;
  125.     in  += plain;
  126.     out += plain;
  127.     outleft -= plain;
  128. backCopy:
  129.     if ( backnum > outleft ) backnum = outleft;
  130.     memcpy(out,out-backoff,backnum);
  131.     out += backnum;
  132.     outleft -= backnum;
  133.     continue;
  134.       case 2:
  135. // 01XXYYYY:YYYYYYYY
  136.     backnum = ((f >> 2) & 3) + 3;
  137.     backoff = (*in++ << 4) + (f >> 4);
  138.     size--;
  139.     goto backCopy;
  140.       case 3: {
  141. //11XXXXYY:YYYYZZZZ:ZZZZZZZZ
  142.     unsigned char yz = *in++;
  143.     unsigned char zz = *in++;
  144.     size--;
  145.     size--;
  146.     plain = (f >> 2) & 0xF;
  147.     backnum = ((f >> 6) & 3) + ((yz & 0xF) << 2);
  148.     backoff = (yz >> 4) + (zz << 4);
  149.     goto fullCopy;
  150.       }
  151.     }
  152.     break;
  153.   }
  154.   if ( outleft > 0 ) memset(out,'\0',outleft);
  155.   return 1;
  156. }
  157. #endif
  158.  
  159.  
  160. unsigned char *
  161. lxPages_get_data(lxfile_t *lx, int pageNum, int fd)
  162. {
  163.     int        i;
  164.     lxPage_t    *p;
  165.  
  166.     if (pageNum < 0 || pageNum >= lx->npages)
  167.         return NULL;
  168.  
  169.     p = lx->pages[pageNum];
  170.     if (p->data == NULL) {
  171.         i = lseek(fd, p->fileOffset, SEEK_SET);
  172.         if (i != p->fileOffset) {
  173.                         fprintf(stderr, "LX-Page %d: error locating offset %#08lx: ",
  174.                                 pageNum, p->fileOffset);
  175.                         perror("");
  176.             return NULL;
  177.         }
  178.  
  179.         trace(8, ("t8>> Getting page %d: %d bytes\n", pageNum, p->rawSz));
  180.         p->data = (unsigned char *) _calloc(lx->lx.PgSize, sizeof(unsigned char));
  181.         i = read(fd, (char *) p->data, p->rawSz);
  182.         if (i != p->rawSz) {
  183.                         fprintf(stderr, "LX-Page %d: error reading %d bytes at %#08lx (%d): ",
  184.                                 pageNum, p->rawSz, p->fileOffset, i);
  185.                         perror("");
  186.             free(p->data);
  187.             p->data = NULL;
  188.             return NULL;
  189.         }
  190.  
  191. #if 0
  192.                 if (p->rawFlags == PAGE_COMPR) {
  193.                         unsigned char   *uncompr;
  194.                         int             rtn;
  195.  
  196.                         trace(8, ("t8>> Uncompressing page %d: ", pageNum));
  197.                         uncompr = (unsigned char *) _calloc(lx->lx.PgSize, sizeof(unsigned char));
  198.                         rtn = lz_expand(p->data, p->rawSz, uncompr, lx->lx.PgSize);
  199.                         if (rtn <= 0) {
  200.                                 fprintf(stderr, "LX-Page %d: de-compression overflow error\n", pageNum);
  201.                                 free(uncompr);
  202.                         }
  203.                         else {
  204.                                 free(p->data);
  205.                                 p->data = uncompr;
  206.                                 p->size = lx->lx.PgSize;
  207.                                 while (p->size > 0 && p->data[p->size - 1] == '\0')
  208.                                         p->size--;
  209.                                 p->flags = PAGE_PHYS;
  210.                                 trace(8, ("rawSz=%d size=%d\n", p->rawSz, p->size));
  211.                         }
  212.                 }
  213. #endif
  214.     }
  215.     return p->data;
  216. }
  217.  
  218. /*
  219.  * Convert a run-time page base address into a file offset in the
  220.  * LX executable file.  A linear search of the page space is sufficient
  221.  * for the needs of the program.
  222.  */
  223. unsigned long
  224. lxPages_get_file_offset(lxfile_t *lx, unsigned long addr)
  225. {
  226.     int    pagenum;
  227.  
  228.     for (pagenum = 0; pagenum < lx->npages; pagenum++) {
  229.         if (lx->pages[pagenum]->addr == addr)
  230.             return lx->pages[pagenum]->fileOffset;
  231.     }
  232.     return 0;
  233. }
  234.  
  235. void
  236. lxPages_set_addr(lxfile_t *lx, int i, unsigned long addr)
  237. {
  238.     if (i < lx->npages)
  239.         lx->pages[i]->addr = addr;
  240.     else {
  241.         fprintf(stderr, "Error bad page number %d\n", i);
  242.         exit(1);
  243.     }
  244. }
  245.  
  246. void
  247. lxPages_set_fixup(lxfile_t *lx, int i, unsigned long offset)
  248. {
  249.     if (i < lx->npages)
  250.         lx->pages[i]->fixupOffset = offset;
  251.     else {
  252.         fprintf(stderr, "Error bad page number %d\n", i);
  253.         exit(1);
  254.     }
  255. }
  256.  
  257. static void
  258. lxPages_print_entry(int i, lxPage_t *p)
  259. {
  260.     trace(6, ("t6>> Page %6d: %#10lx %#10lx %10d %#10x %#10lx %#8lx %#8x ",
  261.         i, p->rawOffset, p->fileOffset,
  262.         p->rawSz, p->rawSz, p->addr, p->fixupOffset, p->rawFlags));
  263.     if (p->rawFlags == PAGE_PHYS)
  264.         trace(6, (" PHYS\n"));
  265.     else if (p->rawFlags == PAGE_ITER)
  266.         trace(6, (" ITER\n"));
  267.     else if (p->rawFlags == PAGE_INVALID)
  268.         trace(6, (" INVALID\n"));
  269.     else if (p->rawFlags == PAGE_ZERO)
  270.         trace(6, (" ZERO\n"));
  271.     else if (p->rawFlags == PAGE_RANGE)
  272.         trace(6, (" RANGE\n"));
  273.     else if (p->rawFlags == PAGE_COMPR)
  274.         trace(6, (" COMPR\n"));
  275.     else
  276.         trace(6, (" ????\n"));
  277. }
  278.  
  279. void
  280. lxPages_print(lxfile_t *lx)
  281. {
  282.         int    i;
  283.  
  284.         trace(6, ("t6>> \n"));
  285.         trace(6, ("t6>> Page             offset fileOffset     pgSize     pgSize  relocAddr fixupOff    flags\n"));
  286.         for (i = 0; i < lx->npages; i++)
  287.                 lxPages_print_entry(i+1, lx->pages[i]);
  288. }
  289.  
  290. int
  291. lxPages_build(int fd, lxfile_t *lx)
  292. {
  293.         int             i, pageno, off;
  294.         LX_PG        pg;
  295.  
  296.         off = lx->mz.lfanew + lx->lx.ObjPgTblOfs;
  297.         i = lseek(fd, off, SEEK_SET);
  298.         if (i != off) {
  299.         fprintf(stderr, "LX-PageTable: error locating offset %#08x: ", off);
  300.         perror("");
  301.         return -1;
  302.     }
  303.  
  304.     lx->pages = (lxPage_t **) _calloc(lx->lx.ModNumPgs, sizeof(lxPage_t *));
  305.     lx->npages = lx->lx.ModNumPgs;
  306.  
  307.         for (pageno = 0; pageno < lx->lx.ModNumPgs; pageno++) {
  308.                 i = read(fd, (char *) &pg, sizeof(pg));
  309.         if (i != sizeof(pg)) {
  310.                         fprintf(stderr, "LX-PageTable %d: error reading %d bytes: ",
  311.                                 i, sizeof(pg));
  312.                         perror("");
  313.             return -1;
  314.         }
  315.  
  316.         if (pg.size > lx->lx.PgSize) {
  317.             fprintf(stderr, "NewPage: page size too large (%d > %ld)\n",
  318.                 pg.size, lx->lx.PgSize);
  319.             continue;
  320.         }
  321.  
  322.         lx->pages[pageno] = lxPages_new(pg.offset, pg.size, pg.flags,
  323.                 (pg.offset << lx->lx.PgOfsShift) + lx->lx.DataPgOfs);
  324.         }
  325.     return 0;
  326. }
  327.