Changeset 8883 for trunk/src


Ignore:
Timestamp:
Jul 17, 2002, 11:09:20 PM (23 years ago)
Author:
achimha
Message:

added more comments, documentation

Location:
trunk/src/kernel32
Files:
2 edited

Legend:

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

    r8877 r8883  
    1 /* $Id: winimagelx.cpp,v 1.15 2002-07-15 14:28:53 sandervl Exp $ */
     1/* $Id: winimagelx.cpp,v 1.16 2002-07-17 21:09:20 achimha Exp $ */
    22
    33/*
     
    123123    ULONG       apiaddr;
    124124
    125     rc = DosQueryProcAddr(hinstanceOS2, dwOrdinalBase+ordinal, NULL, (PFN *)&apiaddr);
     125    rc = DosQueryProcAddr(hinstanceOS2, dwOrdinalBase + ordinal, NULL, (PFN *)&apiaddr);
    126126    if(rc) {
    127127        dprintf(("Win32LxImage::getApi %x %d -> rc = %d", hinstanceOS2, ordinal, rc));
     
    131131}
    132132//******************************************************************************
     133// here we build a fake PE header for an LX module. In Windows, HINSTANCE handles
     134// actually contain the virtual address of of the PE header. We try to fill in
     135// sensible values as much as possible...
    133136//******************************************************************************
    134137LPVOID Win32LxImage::buildHeader(DWORD MajorImageVersion, DWORD MinorImageVersion,
     
    141144    DWORD *ntsig;
    142145
     146    // AH TODO: we are wasting 60k address space here!!!! (at least without PAG_ANY)
    143147    rc = DosAllocMem(&header, 4096, PAG_READ | PAG_WRITE | PAG_COMMIT | flAllocMem);
    144148    if(rc) {
  • trunk/src/kernel32/winimagepeldr.cpp

    r8882 r8883  
    1 /* $Id: winimagepeldr.cpp,v 1.97 2002-07-16 08:16:48 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.98 2002-07-17 21:09:20 achimha Exp $ */
    22
    33/*
     
    580580
    581581#ifdef COMMIT_ALL
     582        // this is a workaround until we have full page fault handling. We
     583        // just commit all pages here, i.e. do the DosReads
    582584        for (i=0; i<nSections; i++) {
    583585            commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
     
    595597        }
    596598#endif
     599        // here we are going to parse the export table and build a list
     600        // in memory of what this module exports
    597601        if(processExports((char *)win32file) == FALSE) {
    598602            dprintf((LOG, "Failed to process exported apis" ));
     
    608612#endif
    609613
    610     //SvL: Use pointer to image header as module handle now. Some apps needs this
     614    // a HINSTANCE in Windows is actually a pointer to the PE header!
    611615    hinstance = (HINSTANCE)realBaseAddress;
    612616
     
    623627    }
    624628
    625     //Allocate TLS index for this module
    626     //Must do this before dlls are loaded for this module. Some apps assume
    627     //they get TLS index 0 for their main executable
     629    // Allocate TLS index for this module
     630    // Must do this before dlls are loaded for this module. Some apps assume
     631    // they get TLS index 0 for their main executable
     632    // AH TODO: is this really safe here? We call processExports before and
     633    // the module might export forwarders so additional DLLs are loaded which
     634    // in turn might allocate TLS in the initterm routine!
    628635    {
    629636      USHORT sel = SetWin32TIB(TIB_SWITCH_FORCE_WIN32);
     
    635642    if(!(dwFlags & (FLAG_PELDR_LOADASDATAFILE | FLAG_PELDR_SKIPIMPORTS)))
    636643    {
     644        // this will process all import statements and resolve them. I.e.
     645        // additional DLLs will be loaded automatically.
    637646        if(processImports((char *)win32file) == FALSE) {
    638647            dprintf((LOG, "Failed to process imports!" ));
     
    728737{
    729738 Section *section;
    730  ULONG    offset, size, sectionsize, protflags, fileoffset, range, attr;
     739 ULONG fileoffset; // this will be the offset in the file we have to read at
     740                   // it will be calculated from the virtual address
     741 ULONG    offset, size, sectionsize, protflags, range, attr;
    731742 ULONG    ulNewPos, ulRead, orgVirtAddress = virtAddress;
    732743 APIRET   rc;
     
    737748    }
    738749
    739     //Round down to nearest page boundary
     750    // round down to nearest page boundary
    740751    virtAddress = virtAddress & ~0xFFF;
    741752
     753    // check if this address corresponds to any PE section
    742754    section = findSectionByOS2Addr(virtAddress);
    743755    if(section == NULL) {
     756        // maybe the section does not start at a page boundary?
    744757        section = findSectionByOS2Addr(orgVirtAddress);
    745758        if(section) {
     
    747760        }
    748761    }
     762    // if we still haven't found the section, it's a special case
    749763    if(section == NULL) {
    750764        size        = 4096;
     
    752766        //Header page must be readonly (same as in NT)
    753767        protflags   = PAG_READ;
     768
     769        // check if there is a previous section
    754770        section = findPreviousSectionByOS2Addr(virtAddress);
    755         if(section == NULL) {//access to header
     771
     772        // no, so it must be the PE header
     773        if(section == NULL) {
    756774            offset     = 0;
    757775            fileoffset = virtAddress - realBaseAddress;
     
    767785        sectionsize = section->virtualsize - offset;
    768786
     787        // check if this is unitialized data (i.e. not present in the PE file
     788        // and set to 0 by the PE loader
    769789        if(offset > section->rawsize || section->type == SECTION_UNINITDATA) {
    770             //unintialized data (set to 0)
     790            // AH TODO shouldn't be abusing these variables here...
    771791            size = 0;
    772792            fileoffset = -1;
    773793        }
    774794        else {
    775             size = section->rawsize-offset;
     795            size = section->rawsize - offset;
    776796            fileoffset = section->rawoffset + offset;
    777797        }
     
    781801        }
    782802    }
    783     if(fPageCmd == COMPLETE_SECTION && (section && section->type == SECTION_DEBUG)) {//ignore
     803    // we completely ignore debug sections!
     804    if(fPageCmd == COMPLETE_SECTION && (section && section->type == SECTION_DEBUG)) {
    784805        return TRUE;
    785806    }
     
    811832    sectionsize = min(sectionsize, range);
    812833
     834    // make sure this is not address space that has no backing PE file data
     835    // (i.e. uninitialized data)
     836    // AH TODO: don't abuse these variables!
    813837    if(size && fileoffset != -1) {
    814838        rc = DosEnterCritSec();
     
    817841            goto fail;
    818842        }
     843        // we need write permissions for now to do the actual loading
    819844        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
    820845        if(rc) {
     
    849874        setFixups(virtAddress, sectionsize);
    850875
     876        // set the protection flags to what the section requests
    851877        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
    852878        DosExitCritSec();
     
    857883    }
    858884    else {
     885        // unitialized data section, padded with 0 (done by OS/2)
     886
    859887        rc = DosEnterCritSec();
    860888        if(rc) {
     
    863891        }
    864892
     893        // get temporary write permission
    865894        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
    866895        if(rc) {
     
    871900        setFixups(virtAddress, sectionsize);
    872901
     902        // set the protection flags to what the section requests
    873903        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
    874904        DosExitCritSec();
     
    925955        return allocFixedMem(reservedMem);
    926956    }
     957    // AH TODO: aren't we wasting 64kb address space here if things go bad?
    927958    rc = OSLibDosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE);
    928959    if(rc) {
     
    10981129}
    10991130//******************************************************************************
     1131// setFixups:
     1132//   this is the main fixup processing function. It uses the virtual image base
     1133//   address (oh.ImageBase) and replaces all fixups by the relative virtual address
     1134//   plus the image base address
    11001135//******************************************************************************
    11011136BOOL Win32PeLdrImage::setFixups(ULONG virtAddress, ULONG size)
    11021137{
    1103  int   i, j;
     1138 int i;
    11041139 char *page;
    11051140 ULONG count, newpage;
     
    11071142 PIMAGE_BASE_RELOCATION prel = pFixups;
    11081143
     1144  // is fixup processing required?
    11091145  if(realBaseAddress == oh.ImageBase || fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    11101146        return(TRUE);
    11111147  }
    11121148
     1149  // convert the virtual address to a relative virtual address
    11131150  virtAddress -= realBaseAddress;
    1114   //round size to next page boundary
    1115   size  = (size-1) & ~0xFFF;
     1151
     1152  // round size to next page boundary
     1153  size  = (size - 1) & ~0xFFF;
    11161154  size += PAGE_SIZE;
    11171155
     1156  // do we have relocation records (aka fixups)?
    11181157  if(prel) {
    1119         j = 1;
    1120         while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
     1158        // move to the first relocation record
     1159        while(((ULONG)prel < (ULONG)pFixups + dwFixupSize) &&
    11211160              prel->VirtualAddress && prel->VirtualAddress < virtAddress)
    11221161        {
    11231162            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
    11241163        }
    1125         while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
     1164        // go through all relocation records
     1165        while(((ULONG)prel < (ULONG)pFixups + dwFixupSize) &&
    11261166               prel->VirtualAddress && prel->VirtualAddress < virtAddress + size)
    11271167        {
    11281168            page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
    1129             count  = (prel->SizeOfBlock - 8)/2;
    1130             j++;
    1131             for(i=0;i<count;i++) {
     1169            // determine how many fixups we have to process
     1170            count = (prel->SizeOfBlock - 8) / 2;
     1171            for(i = 0; i < count; i++) {
    11321172                int type   = prel->TypeOffset[i] >> 12;
    11331173                int offset = prel->TypeOffset[i] & 0xFFF;
     
    11441184                    break;
    11451185                }
    1146                 //If the fixup crosses the final page boundary,
    1147                 //then we have to load another page
     1186                // if the fixup crosses the final page boundary,
     1187                // then we have to load another page
    11481188                if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
    11491189                {
     
    11511191                    newpage &= ~0xFFF;
    11521192
     1193                    // find the corresponding section so that we know lateron
     1194                    // what permission bits we have to assign to the new page
    11531195                    section  = findSectionByOS2Addr(newpage);
    11541196                    if(section == NULL) {
    1155                         //should never happen
    1156                         dprintf((LOG, "::setFixups -> section == NULL!!"));
     1197                        // should never happen
     1198                        dprintf((LOG, "setFixups -> section == NULL!!"));
    11571199                        return FALSE;
    11581200                    }
    1159                     //SvL: Read page from disk
     1201                    // explicitly read page from disk
    11601202                    commitPage(newpage, FALSE, SINGLE_PAGE);
    11611203
    11621204                    //SvL: Enable write access (TODO: may need to prevent other threads from being active)
    1163                     DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE);
     1205                    DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ | PAG_WRITE);
    11641206                }
    11651207
     
    11821224                        break;
    11831225                }
     1226                // did we have to load another page?
    11841227                if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
    11851228                {
     
    11881231                }
    11891232            }
     1233            // move to the next relocation record
    11901234            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
    11911235        }//while
     
    12011245BOOL Win32PeLdrImage::setFixups(PIMAGE_BASE_RELOCATION prel)
    12021246{
    1203  int   i, j;
     1247 int   i;
     1248 #if DEBUG
     1249 int j;
     1250 #endif
    12041251 char *page;
    12051252 ULONG count;
    12061253
     1254  // if there are no fixups, we have nothing to do...
    12071255  if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    12081256        return(TRUE);
     
    12101258
    12111259  if(prel) {
     1260        #if DEBUG
    12121261        j = 1;
     1262        #endif
     1263        // loop through all relocation records
    12131264        while(prel->VirtualAddress) {
    12141265            page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
    1215             count  = (prel->SizeOfBlock - 8)/2;
    1216             dprintf((LOG, "Page %d Address %x Count %d", j, prel->VirtualAddress, count ));
     1266            // determine how many fixups we have to process
     1267            count  = (prel->SizeOfBlock - 8) / 2;
     1268
     1269            dprintf((LOG, "Page %d Address %x Count %d", j, prel->VirtualAddress, count));
     1270            #if DEBUG
    12171271            j++;
    1218             for(i=0;i<count;i++) {
     1272            #endif
     1273
     1274            for(i = 0; i < count; i++) {
    12191275                int type   = prel->TypeOffset[i] >> 12;
    12201276                int offset = prel->TypeOffset[i] & 0xFFF;
     
    12401296                }
    12411297            }
     1298            // advance to the next relocation record
    12421299            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
    12431300        }//while
     
    12591316    fixup   = (ULONG *)(fixupaddr + realBaseAddress);
    12601317    orgaddr = *fixup;
    1261 //  dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - oh.ImageBase)));
     1318////  dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - oh.ImageBase)));
    12621319    *fixup  = realBaseAddress + (*fixup - oh.ImageBase);
    12631320}
     
    15621619    }
    15631620
     1621    // if it's not a PE image, we let OS/2 load it (LX image)
    15641622    if(isPEImage(modname, NULL, NULL) != ERROR_SUCCESS_W)
    1565     {//LX image, so let OS/2 do all the work for us
     1623    {
    15661624        APIRET rc;
    15671625        char   szModuleFailure[CCHMAXPATH] = "";
     
    15691627        Win32LxDll *lxdll;
    15701628
     1629        // check if we have the .DLL extension or have to add it first
    15711630        char *dot = strchr(modname, '.');
    15721631        if(dot == NULL) {
    15731632            strcat(modname, DLL_EXTENSION);
    15741633        }
     1634        // here we load the module. This will also execute the initterm
     1635        // function in the DLL. We expect the LX DLL to callback RegisterLxDll
     1636        // to register with Odin. This also means we cannot load "standard"
     1637        // LX DLLs with this method - they have to be Odin aware
    15751638        rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll);
    15761639        if(rc) {
     
    15801643            return NULL;
    15811644        }
     1645        // due to the callback requirement, we can expect to have a structure
     1646        // for it by now. Otherwise it didn't work out
    15821647        lxdll = Win32LxDll::findModuleByOS2Handle(hInstanceNewDll);
    15831648        if(lxdll == NULL) {//shouldn't happen!
    15841649            dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?"));
     1650            // AH TODO: shouldn't we do a DosFreeModule here?
    15851651            errorState = ERROR_INTERNAL;
    15861652            return NULL;
    15871653        }
    15881654        lxdll->setDllHandleOS2(hInstanceNewDll);
     1655        // AddRef for a LX DLL is special - it does not increase the reference counter
    15891656        if(lxdll->AddRef() == -1) {//-1 -> load failed (attachProcess)
    15901657            dprintf((LOG, "Dll %s refused to be loaded; aborting", modname));
     
    15971664    else {
    15981665         Win32PeLdrDll *pedll;
    1599 
     1666            // create an object for that DLL
    16001667            pedll = new Win32PeLdrDll(modname, this);
    16011668            if(pedll == NULL) {
     
    16081675            dprintf((LOG, "**********************     Loading Module        *********************" ));
    16091676            dprintf((LOG, "**********************************************************************" ));
     1677            // do the actual loading including all imports - so this is a point of recursion
    16101678            if(pedll->init(0) == FALSE) {
    16111679                dprintf((LOG, "Internal WinDll error ", pedll->getError() ));
     
    16161684            pedll->AddRef(getModuleName());
    16171685#else
     1686            // increase the reference count
    16181687            pedll->AddRef();
    16191688#endif
     1689            // send the attach process message to the DLL, i.e. call the handler
    16201690            if(pedll->attachProcess() == FALSE) {
    16211691                dprintf((LOG, "attachProcess failed!" ));
     
    20522122}
    20532123//******************************************************************************
     2124// we link this function to all imports we couldn't resolve in our DLLs so the
     2125// user gets a stupid error message dialog
    20542126//******************************************************************************
    20552127ULONG WIN32API MissingApi(char *message)
Note: See TracChangeset for help on using the changeset viewer.