Ignore:
Timestamp:
Aug 18, 1999, 7:18:01 PM (26 years ago)
Author:
sandervl
Message:

PE loader changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/winimage.cpp

    r544 r550  
    1 /* $Id: winimage.cpp,v 1.10 1999-08-18 12:24:16 sandervl Exp $ */
     1/* $Id: winimage.cpp,v 1.11 1999-08-18 17:18:01 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998 Knut St. Osmundsen
    8  *
    98 *
    109 * Project Odin Software License can be found in LICENSE.TXT
     
    3534#include "unicode.h"
    3635#include "winres.h"
     36#include "os2util.h"
    3737
    3838char szErrorTitle[]     = "Win32 for OS/2";
     
    5858Win32Image::Win32Image(char *szFileName) :
    5959    errorState(NO_ERROR), entryPoint(0), nrsections(0), imageSize(0),
    60     imageVirtBase(-1), baseAddress(0), realBaseAddress(0), imageVirtEnd(0),
     60    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    6161    nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
    6262    szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
     
    7373    foutInit = TRUE;
    7474  }
    75   hinstance = (HINSTANCE)this;
    7675  this->szFileName = szFileName;
     76
     77  strcpy(szModule, StripPath(szFileName));
     78  strupr(szModule);
     79  char *dot = strstr(szModule, ".");
     80  while(dot) {
     81        char *newdot = strstr(dot+1, ".");
     82        if(newdot == NULL)      break;
     83        dot = newdot;
     84  }
     85  if(dot)
     86        *dot = 0;
     87
    7788#ifdef DEBUG
    7889  magic = MAGIC_WINIMAGE;
     
    8394Win32Image::Win32Image(HINSTANCE hinstance, int NameTableId, int Win32TableId) :
    8495    errorState(NO_ERROR), entryPoint(0), nrsections(0), imageSize(0),
    85     imageVirtBase(-1), baseAddress(0), realBaseAddress(0), imageVirtEnd(0),
     96    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    8697    nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
    8798    szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
     
    93104#endif
    94105  OS2ImageInit(hinstance, NameTableId, Win32TableId);
     106
     107  char *name = OS2GetDllName(hinstance);
     108  strcpy(szModule, name);
     109  strupr(szModule);
     110  char *dot = strstr(szModule, ".");
     111  while(dot) {
     112        char *newdot = strstr(dot+1, ".");
     113        if(newdot == NULL)      break;
     114        dot = newdot;
     115  }
     116  if(dot)
     117        *dot = 0;
    95118}
    96119//******************************************************************************
     
    378401  }
    379402  fout << "*************************PE SECTIONS END **************************" << endl;
    380   imageSize += (imageVirtBase - oh.ImageBase);
     403  imageSize += imageVirtBase - oh.ImageBase;
    381404  fout << "Total size of Image " << imageSize << endl;
    382405  fout << "imageVirtBase       " << imageVirtBase << endl;
    383406  fout << "imageVirtEnd        " << imageVirtEnd << endl;
    384407
     408  //In case there are any gaps between sections, adjust size
    385409  if(imageSize != imageVirtEnd - oh.ImageBase) {
    386410        fout << "imageSize != imageVirtEnd - oh.ImageBase!" << endl;
     
    391415        return(FALSE);
    392416  }
    393   fout << "OS/2 base address " << baseAddress << endl;
    394   if(storeSections() == FALSE) {
     417  fout << "OS/2 base address " << realBaseAddress << endl;
     418  if(storeSections((char *)win32file) == FALSE) {
    395419        fout << "Failed to store sections, rc " << errorState << endl;
    396420        return(FALSE);
    397421  }
    398   entryPoint = baseAddress + oh.AddressOfEntryPoint;
     422  entryPoint = realBaseAddress + oh.AddressOfEntryPoint;
    399423
    400424  if(tlsDir != NULL) {
     
    447471        pResDir = (PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE);
    448472  }
     473
     474  //SvL: Use pointer to image header as module handle now. Some apps needs this
     475  hinstance = (HINSTANCE)realBaseAddress;
     476
    449477  //set final memory protection flags (storeSections sets them to read/write)
    450478  if(setMemFlags() == FALSE) {
     
    474502  virtsize   = ((virtsize - 1) & ~0xFFF) + PAGE_SIZE;
    475503  imageSize += virtsize;
    476   section[nrsections].virtualsize    = virtsize;
     504  section[nrsections].virtualsize = virtsize;
    477505
    478506  if(virtaddress < imageVirtBase)
    479507        imageVirtBase = virtaddress;
    480508  if(virtaddress + virtsize > imageVirtEnd)
    481         imageVirtEnd = virtaddress + virtsize;
     509        imageVirtEnd  = virtaddress + virtsize;
    482510
    483511  nrsections++;
     
    488516{
    489517 APIRET rc;
     518 ULONG  baseAddress;
    490519
    491520  if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
     
    525554//******************************************************************************
    526555#define FALLOC_SIZE (1024*1024)
     556//NOTE: Needs testing (while loop)
     557//TODO: Free unused (parts of) reservedMem
    527558//******************************************************************************
    528559BOOL Win32Image::allocFixedMem(ULONG reservedMem)
    529560{
    530561 ULONG  address = 0;
    531  ULONG  lastaddress = 0;
    532  ULONG  firstaddress = 0;
    533  ULONG  diff, i;
     562 ULONG  *memallocs;
     563 ULONG  alloccnt = 0;
     564 ULONG  diff, i, baseAddress;
    534565 APIRET rc;
    535566
    536   baseAddress = realBaseAddress = 0;
     567  realBaseAddress = 0;
    537568 
    538569  if(reservedMem && reservedMem <= oh.ImageBase &&
     
    541572        //ok, it fits perfectly
    542573        realBaseAddress = oh.ImageBase;
    543         baseAddress = oh.ImageBase;
    544574        return TRUE;
     575  }
     576
     577  //Reserve enough space to store 4096 pointers to 1MB memory chunks
     578  memallocs = (ULONG *)malloc(4096*sizeof(ULONG *));
     579  if(memallocs == NULL) {
     580        fout << "allocFixedMem: MALLOC FAILED for memallocs" << endl;
     581        return FALSE;
    545582  }
    546583
     
    548585        rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ);
    549586        if(rc) break;
    550 
    551         if(firstaddress == 0)
    552                 firstaddress = address;
    553587
    554588        fout << "DosAllocMem returned " << address << endl;
     
    556590                if(address > oh.ImageBase) {//we've passed it!
    557591                        DosFreeMem((PVOID)address);
    558                         return(FALSE);
     592                        break;
    559593                }
    560594                //found the right address
    561595                DosFreeMem((PVOID)address);
    562                 //align at 64 kb boundary
    563                 realBaseAddress = oh.ImageBase & 0xFFFF0000;
    564                 diff = realBaseAddress - address;
     596
     597                diff = address - oh.ImageBase;
    565598                if(diff) {
    566599                        rc = DosAllocMem((PPVOID)&address, diff, PAG_READ);
     
    570603                if(rc) break;
    571604
    572                 if(baseAddress != realBaseAddress) {
    573                         fout << "baseAddress != realBaseAddress!!" << endl;
    574                         break;
    575                 }
    576605                if(diff) DosFreeMem((PVOID)address);
    577606
    578                 address = realBaseAddress;
    579607                realBaseAddress = baseAddress;
    580                 baseAddress = oh.ImageBase;
    581608                break;
    582609        }
    583         lastaddress = address;
    584   }
    585   while(firstaddress <= lastaddress) {
    586         DosFreeMem((PVOID)firstaddress);
    587         firstaddress += FALLOC_SIZE;
    588   }
    589   if(baseAddress == 0) //Let me guess.. MS Office app?
     610        memallocs[alloccnt++] = address;
     611  }
     612  for(i=0;i<alloccnt;i++) {
     613        DosFreeMem((PVOID)memallocs[i]);
     614  }
     615  free(memallocs);
     616
     617  if(realBaseAddress == 0) //Let me guess.. MS Office app?
    590618        return(FALSE);
    591619
     
    594622//******************************************************************************
    595623//******************************************************************************
    596 BOOL Win32Image::storeSections()
     624BOOL Win32Image::storeSections(char *win32file)
    597625{
    598626 int i;
    599627 APIRET rc;
    600628 ULONG  pagFlags = PAG_COMMIT;
    601 
     629 ULONG  headersize;
     630 WINIMAGE_LOOKUP *imgLookup;
     631
     632  //Commit memory for image header
     633  headersize = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) +
     634               sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections;
     635
     636  if(headersize + sizeof(WINIMAGE_LOOKUP) < PAGE_SIZE) {
     637        headersize = PAGE_SIZE;
     638  }
     639  else {//ooops, just in case this doesn't work
     640        fout << "ERROR: storeSections: header too big!!!!!! Fatal error" << endl;
     641        return FALSE;
     642  }
     643
     644  rc = DosSetMem((PVOID)realBaseAddress, headersize, pagFlags | PAG_WRITE | PAG_READ);
     645  if(rc) {
     646        fout << "DosSetMem failed for Image header! " << rc << endl;
     647        return FALSE;
     648  }
     649  // Store the NT header at the load addr
     650  memcpy((char *)realBaseAddress, win32file, sizeof(IMAGE_DOS_HEADER));
     651  memcpy((char *)PE_HEADER(realBaseAddress), PE_HEADER(win32file), sizeof(IMAGE_NT_HEADERS));
     652  memcpy(PE_SECTIONS(realBaseAddress), PE_SECTIONS(win32file),
     653         sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections );
     654
     655  imgLookup = WINIMAGE_LOOKUPADDR(realBaseAddress);
     656  imgLookup->image = this;
     657  imgLookup->magic = MAGIC_WINIMAGE;
     658
     659  // Process all the image sections
    602660  for(i=0;i<nrsections;i++) {
    603         section[i].realvirtaddr = baseAddress + (section[i].virtaddr - oh.ImageBase);
     661        section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase);
    604662  }
    605663  for(i=0;i<nrsections;i++) {
     
    735793 ULONG *fixup;
    736794
    737   fixup   = (ULONG *)(fixupaddr - oh.ImageBase + baseAddress);
     795  fixup   = (ULONG *)(fixupaddr - oh.ImageBase + realBaseAddress);
    738796  orgaddr = *fixup;
    739   *fixup  = baseAddress + (*fixup - oh.ImageBase);
     797  *fixup  = realBaseAddress + (*fixup - oh.ImageBase);
    740798}
    741799//******************************************************************************
     
    746804 USHORT *fixup;
    747805
    748   fixup   = (USHORT *)(fixupaddr - oh.ImageBase + baseAddress);
     806  fixup   = (USHORT *)(fixupaddr - oh.ImageBase + realBaseAddress);
    749807  orgaddr = *fixup;
    750808  if(fHighFixup) {
    751         *fixup  += (USHORT)((baseAddress - oh.ImageBase) >> 16);
     809        *fixup  += (USHORT)((realBaseAddress - oh.ImageBase) >> 16);
    752810  }
    753811  else {
    754         *fixup  += (USHORT)((baseAddress - oh.ImageBase) & 0xFFFF);
     812        *fixup  += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF);
    755813  }
    756814}
     
    762820 ULONG  apiaddr;
    763821
    764   import  = (ULONG *)(impaddr - oh.ImageBase + baseAddress);
     822  import  = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
    765823  apiaddr = WinDll->getApi(ordinal);
    766824  if(apiaddr == 0) {
     
    777835 ULONG  apiaddr;
    778836
    779   import = (ULONG *)(impaddr - oh.ImageBase + baseAddress);
     837  import = (ULONG *)(impaddr - oh.ImageBase + realBaseAddress);
    780838  apiaddr = WinDll->getApi(impname);
    781839  if(apiaddr == 0) {
     
    893951        free(tmp);
    894952  }
    895   curnameexport->virtaddr = baseAddress + (virtaddr - oh.ImageBase);
     953  curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    896954  curnameexport->ordinal  = ordinal;
    897955  *(ULONG *)curnameexport->name = 0;
     
    912970        curordexport = ordexports;
    913971  }
    914   curordexport->virtaddr = baseAddress + (virtaddr - oh.ImageBase);
     972  curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    915973  curordexport->ordinal  = ordinal;
    916974  curordexport++;
     
    12411299  return(0);
    12421300}
    1243 //******************************************************************************
    1244 //******************************************************************************
     1301/******************************************************************************/
     1302/******************************************************************************/
    12451303/*heximal(decimal) KSO Sun 24.05.1998*/
    12461304char szHexBuffer[30];
Note: See TracChangeset for help on using the changeset viewer.