Example #1
0
static BOOL
FinalizeSections(PMEMORYMODULE module)
{
    int i;
    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
#ifdef _WIN64
    uintptr_t imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000);
#else
    #define imageOffset 0
#endif
    SECTIONFINALIZEDATA sectionData;
    sectionData.address = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
    sectionData.alignedAddress = ALIGN_DOWN(sectionData.address, module->pageSize);
    sectionData.size = GetRealSectionSize(module, section);
    sectionData.characteristics = section->Characteristics;
    sectionData.last = FALSE;
    section++;

    // loop through all sections and change access flags
    for (i=1; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
        LPVOID sectionAddress = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
        LPVOID alignedAddress = ALIGN_DOWN(sectionAddress, module->pageSize);
        DWORD sectionSize = GetRealSectionSize(module, section);
        // Combine access flags of all sections that share a page
        // TODO(fancycode): We currently share flags of a trailing large section
        //   with the page of a first small section. This should be optimized.
        if (sectionData.alignedAddress == alignedAddress || (uintptr_t) sectionData.address + sectionData.size > (uintptr_t) alignedAddress) {
            // Section shares page with previous
            if ((section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0) {
                sectionData.characteristics = (sectionData.characteristics | section->Characteristics) & ~IMAGE_SCN_MEM_DISCARDABLE;
            } else {
                sectionData.characteristics |= section->Characteristics;
            }
            sectionData.size = (DWORD)((((uintptr_t)sectionAddress) + sectionSize) - (uintptr_t) sectionData.address);
            continue;
        }

        if (!FinalizeSection(module, &sectionData)) {
            return FALSE;
        }
        sectionData.address = sectionAddress;
        sectionData.alignedAddress = alignedAddress;
        sectionData.size = sectionSize;
        sectionData.characteristics = section->Characteristics;
    }
    sectionData.last = TRUE;
    if (!FinalizeSection(module, &sectionData)) {
        return FALSE;
    }
#ifndef _WIN64
#undef imageOffset
#endif
    return TRUE;
}
	//=============================================================================
	//
	//
	//
	//=============================================================================
	bool CreateSections()
	{
		int pick = 0;

		MarkInternalSubsectors();
		while (pick < numsubsectors)
		{
			if (ISDONE(pick, processed_subsectors)) 
			{
				pick++;
				continue;
			}


			subsector_t *subsector = &subsectors[pick];

			seg_t *workseg = NULL;
			vertex_t *startpt = NULL;

			NewSection(subsector->render_sector);
			while (1)
			{
				if (!ISDONE(subsector-subsectors, processed_subsectors))
				{
					SETDONE(subsector-subsectors, processed_subsectors);
					section->subsectors.Push(subsector);
					SectionForSubsector[subsector - subsectors] = int(section - &Sections[0]);
				}

				bool result = AddSubSector(subsector, startpt, &workseg);

				if (!result)
				{
					return false;	// couldn't create Sections
				}
				else if (workseg != NULL)
				{
					// crossing into another subsector
					seg_t *partner = workseg->PartnerSeg;
					if (workseg->v2 != partner->v1)
					{
						DPrintf("Inconsistent subsector references in seg %d. Cannot create Sections.\n", workseg-segs);
						return false;
					}
					subsector = partner->Subsector;
					startpt = workseg->v1;
				}
				else
				{
					// loop complete. Check adjoining subsectors for other loops to
					// be added to this section
					if (!FindNextSeg(&workseg))
					{
						return false;
					}
					else if (workseg == NULL)
					{
						// No more subsectors found. This section is complete!
						FinalizeSection();
						break;
					}
					else
					{
						subsector = workseg->Subsector;
						// If this is a regular seg, start there, otherwise start
						// at the subsector's first seg
						startpt = workseg->sidedef == NULL? NULL : workseg->v1;

						NewLoop();
					}
				}
			}
		}

		if (!CheckSections()) return false;
		SetReferences();

		Sections.ShrinkToFit();
		SectionLoops.ShrinkToFit();
		SectionLines.ShrinkToFit();

		tesselateSections();

		return true;
	}