示例#1
0
bool FEncryptXorCopyFile(FILE* a_fpDest, FILE* a_fpSrc, const char* a_pXorFileName, n64 a_nOffset, n64 a_nSize, bool a_bVerbose)
{
	FILE* fpXor = FFopen(a_pXorFileName, "rb");
	if (fpXor == nullptr)
	{
		return false;
	}
	FFseek(fpXor, 0, SEEK_END);
	n64 nXorSize = FFtell(fpXor);
	if (nXorSize < a_nSize && a_bVerbose)
	{
		fclose(fpXor);
		printf("ERROR: xor file %s size less than data size\n\n", a_pXorFileName);
		return false;
	}
	FFseek(fpXor, 0, SEEK_SET);
	const n64 nBufferSize = 0x100000;
	u8* pDataBuffer = new u8[nBufferSize];
	u8* pXorBuffer = new u8[nBufferSize];
	FFseek(a_fpSrc, a_nOffset, SEEK_SET);
	while (a_nSize > 0)
	{
		n64 nSize = a_nSize > nBufferSize ? nBufferSize : a_nSize;
		fread(pDataBuffer, 1, static_cast<size_t>(nSize), a_fpSrc);
		fread(pXorBuffer, 1, static_cast<size_t>(nSize), fpXor);
		u64* pDataBuffer64 = reinterpret_cast<u64*>(pDataBuffer);
		u64* pXorBuffer64 = reinterpret_cast<u64*>(pXorBuffer);
		n64 nXorCount = FAlign(nSize, 8) / 8;
		for (n64 i = 0; i < nXorCount; i++)
		{
			*pDataBuffer64++ ^= *pXorBuffer64++;
		}
		fwrite(pDataBuffer, 1, static_cast<size_t>(nSize), a_fpDest);
		a_nSize -= nSize;
	}
	delete[] pXorBuffer;
	delete[] pDataBuffer;
	fclose(fpXor);
	return true;
}
示例#2
0
bool FEncryptXorFile(const char* a_pDataFileName, const char* a_pXorFileName, n64 a_nDataOffset, n64 a_nDataSize, bool a_bDataFileAll, n64 a_nXorOffset, bool a_bVerbose)
{
	FILE* fpData = FFopen(a_pDataFileName, "rb+");
	if (fpData == nullptr)
	{
		return false;
	}
	FFseek(fpData, 0, SEEK_END);
	n64 nDataSize = FFtell(fpData);
	if (nDataSize < a_nDataOffset)
	{
		fclose(fpData);
		printf("ERROR: data file %s size less than data offset\n\n", a_pDataFileName);
		return false;
	}
	if (a_bDataFileAll)
	{
		a_nDataSize = nDataSize - a_nDataOffset;
	}
	if (nDataSize < a_nDataOffset + a_nDataSize)
	{
		if (a_bVerbose)
		{
			fclose(fpData);
			printf("ERROR: data file %s size less than data offset + data size\n\n", a_pDataFileName);
			return false;
		}
		a_nDataSize = nDataSize - a_nDataOffset;
	}
	FILE* fpXor = FFopen(a_pXorFileName, "rb");
	if (fpXor == nullptr)
	{
		fclose(fpData);
		return false;
	}
	FFseek(fpXor, 0, SEEK_END);
	n64 nXorSize = FFtell(fpXor);
	if (nXorSize - a_nXorOffset < a_nDataSize)
	{
		if (a_bVerbose)
		{
			fclose(fpXor);
			fclose(fpData);
			printf("ERROR: xor file %s size less than data size\n\n", a_pXorFileName);
			return false;
		}
		a_nDataSize = nXorSize - a_nXorOffset;
	}
	FFseek(fpXor, a_nXorOffset, SEEK_SET);
	n64 nIndex = 0;
	const n64 nBufferSize = 0x100000;
	u8* pDataBuffer = new u8[nBufferSize];
	u8* pXorBuffer = new u8[nBufferSize];
	while (a_nDataSize > 0)
	{
		n64 nSize = a_nDataSize > nBufferSize ? nBufferSize : a_nDataSize;
		FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET);
		fread(pDataBuffer, 1, static_cast<size_t>(nSize), fpData);
		fread(pXorBuffer, 1, static_cast<size_t>(nSize), fpXor);
		u64* pDataBuffer64 = reinterpret_cast<u64*>(pDataBuffer);
		u64* pXorBuffer64 = reinterpret_cast<u64*>(pXorBuffer);
		n64 nXorCount = FAlign(nSize, 8) / 8;
		for (n64 i = 0; i < nXorCount; i++)
		{
			*pDataBuffer64++ ^= *pXorBuffer64++;
		}
		FFseek(fpData, a_nDataOffset + nIndex * nBufferSize, SEEK_SET);
		fwrite(pDataBuffer, 1, static_cast<size_t>(nSize), fpData);
		a_nDataSize -= nSize;
		nIndex++;
	}
	delete[] pXorBuffer;
	delete[] pDataBuffer;
	fclose(fpXor);
	fclose(fpData);
	return true;
}
void* FMallocBinned::realloc(void* origin, size_t newSize, uint32_t alignment)
{
    // Handle DefaultAlignment for binned allocator.
    if (alignment == DefaultAlignment)
    {
        alignment = default_binned_allocator_alignment;
    }

    FAssert(alignment <= pageSize);

    alignment = std::max<uint32_t>(alignment, default_binned_allocator_alignment);

    if (newSize)
    {
        newSize = std::max<size_t>(alignment, FAlign(newSize, alignment));
    }

    MEM_TIME(MemTime -= FPlatformTime::Seconds());

    UIntPtr_t basePtr;

    void* newPtr = origin;

    if( origin && newSize )
    {
        FPoolInfo* pool = findPoolInfo((UIntPtr_t)origin, basePtr);

        if( pool->tableIndex < binnedOSTableIndex )
        {
            // Allocated from pool, so grow or shrink if necessary.
            FAssert(pool->tableIndex > 0); // it isn't possible to allocate a size of 0, Malloc will increase the size to default_binned_allocator_alignment

            const uint32_t thisTableBlockSize = memSizeToPoolTable[pool->tableIndex]->blockSize;

            if( newSize > thisTableBlockSize || newSize <= memSizeToPoolTable[pool->tableIndex - 1]->blockSize )
            {
                newPtr = this->malloc( newSize, alignment );
                FMemory::memcpy( newPtr, origin, std::min<size_t>( newSize, thisTableBlockSize ) );
                this->free( origin );
            }
        }
        else
        {
            // Allocated from OS.
            FAssert(!((UIntPtr_t)origin & (pageSize-1)));

            if( newSize > pool->getOsBytes(pageSize, (int32_t)binnedOSTableIndex)
               || newSize * 3 < pool->getOsBytes(pageSize, (uint32_t)binnedOSTableIndex) * 2 )
            {
                // Grow or shrink.
                newPtr = this->malloc( newSize, alignment );
                FMemory::memcpy( newPtr, origin, std::min<size_t>(newSize, pool->getBytes()) );
                this->free( origin );
            }
            else
            {
                // Keep as-is, reallocation isn't worth the overhead.
                STAT(usedCurrent += newSize - pool->getBytes());
                STAT(usedPeak = std::max(usedPeak, usedCurrent));
                STAT(wasteCurrent += pool->getBytes() - newSize);
                pool->setAllocationSizes((uint32_t)newSize, pool->getOsBytes(pageSize, (uint32_t)binnedOSTableIndex), (uint32_t)binnedOSTableIndex, (uint32_t)binnedOSTableIndex);
            }
        }
    }
    else if( origin == nullptr )
    {
        newPtr = this->malloc( newSize, alignment );
    }
    else
    {
        this->free( origin );
        newPtr = nullptr;
    }
    
    MEM_TIME(MemTime += FPlatformTime::Seconds());
    return newPtr;
}
void* FMallocBinned::malloc(size_t size, uint32_t alignment)
{
#ifdef USE_COARSE_GRAIN_LOCKS
    FScopeLock ScopedLock(&AccessGuard);
#endif

    flushPendingFrees();

    // Handle DEFAULT_ALIGNMENT for binned allocator.
    if (alignment == DefaultAlignment)
    {
        alignment = default_binned_allocator_alignment;
    }

    FAssert(alignment <= pageSize);

    alignment = std::max<uint32_t>(alignment, default_binned_allocator_alignment);

    size = std::max<size_t>(alignment, FAlign(size, alignment));

    MEM_TIME(MemTime -= FPlatformTime::Seconds());

    STAT(currentAllocs++);
    STAT(totalAllocs++);

    FFreeMem* free = nullptr;

    if( size < binnedSizeLimit )
    {
        // Allocate from pool.
        FPoolTable* table = memSizeToPoolTable[size];
#ifdef USE_FINE_GRAIN_LOCKS
        std::lock_guard<std::mutex> tableLock(table->mutex);
#endif
        FAssert(size <= table->blockSize);

        trackStats(table, (uint32_t)size);

        FPoolInfo* pool = table->firstPool;
        if( !pool )
        {
            pool = allocatePoolMemory(table, binned_alloc_pool_size/*PageSize*/, size);
        }

        free = allocateBlockFromPool(table, pool);
    }
    else if ( ((size >= binnedSizeLimit && size <= pagePoolTable[0].blockSize) ||
               (size > pageSize && size <= pagePoolTable[1].blockSize))
             && alignment == default_binned_allocator_alignment )
    {
        // Bucket in a pool of 3*PageSize or 6*PageSize
        uint32_t binType = size < pageSize ? 0 : 1;
        uint32_t pageCount = 3 * binType + 3;

        FPoolTable* table = &pagePoolTable[binType];
#ifdef USE_FINE_GRAIN_LOCKS
        std::lock_guard<std::mutex> tableLock(table->mutex);
#endif
        FAssert(size <= table->blockSize);

        trackStats(table, (uint32_t)size);

        FPoolInfo* pool = table->firstPool;
        if( !pool )
        {
            pool = allocatePoolMemory(table, pageCount * pageSize, binnedSizeLimit + binType);
        }

        free = allocateBlockFromPool(table, pool);
    }
    else
    {
        // Use OS for large allocations.
        UIntPtr_t alignedSize = FAlign(size, pageSize);

        size_t actualPoolSize; //TODO: use this to reduce waste?
        free = (FFreeMem*)osAlloc(alignedSize, actualPoolSize);
        if( !free )
        {
            outOfMemory(alignedSize);
        }

        FAssert(!((size_t)free & (pageSize - 1)));

        // Create indirect.
        FPoolInfo* pool;
        {
#ifdef USE_FINE_GRAIN_LOCKS
            std::lock_guard<std::mutex> poolInfoLock(accessGuard);
#endif
            pool = getPoolInfo((UIntPtr_t)free);
        }

        pool->setAllocationSizes((uint32_t)size, alignedSize, (uint32_t)binnedOSTableIndex, (uint32_t)binnedOSTableIndex);

        STAT(osPeak = std::max(osPeak, osCurrent += alignedSize));
        STAT(usedPeak = std::max(usedPeak, usedCurrent += size));
        STAT(wastePeak = std::max(wastePeak, wasteCurrent += alignedSize - size));
    }
    
    MEM_TIME(MemTime += FPlatformTime::Seconds());
    return free;

}