Skip to content

Commit

Permalink
Merge pull request #50 from fancycode/fix_64bit_warnings
Browse files Browse the repository at this point in the history
Fix various 64bit issues
  • Loading branch information
fancycode authored Sep 19, 2016
2 parents 8988355 + 097403a commit 221a470
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 23 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ endif ()
if (NOT MSVC)
add_definitions ("-Wall")
else ()
# Show level 4 warnings.
add_definitions ("-W4")
endif ()

Expand Down
110 changes: 98 additions & 12 deletions MemoryModule.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
#if _MSC_VER
// Disable warning about data -> function pointer conversion
#pragma warning(disable:4055)
// C4244: conversion from 'uintptr_t' to 'DWORD', possible loss of data.
#pragma warning(error: 4244)
// C4267: conversion from 'size_t' to 'int', possible loss of data.
#pragma warning(error: 4267)

#define inline __inline
#endif

#ifndef IMAGE_SIZEOF_BASE_RELOCATION
Expand Down Expand Up @@ -68,14 +74,27 @@ typedef struct {
typedef struct {
LPVOID address;
LPVOID alignedAddress;
DWORD size;
SIZE_T size;
DWORD characteristics;
BOOL last;
} SECTIONFINALIZEDATA, *PSECTIONFINALIZEDATA;

#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
#define ALIGN_DOWN(address, alignment) (LPVOID)((uintptr_t)(address) & ~((alignment) - 1))
#define ALIGN_VALUE_UP(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1))

static inline uintptr_t
AlignValueDown(uintptr_t value, uintptr_t alignment) {
return value & ~(alignment - 1);
}

static inline LPVOID
AlignAddressDown(LPVOID address, uintptr_t alignment) {
return (LPVOID) AlignValueDown((uintptr_t) address, alignment);
}

static inline size_t
AlignValueUp(size_t value, size_t alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}

#ifdef DEBUG_OUTPUT
static void
Expand Down Expand Up @@ -173,7 +192,7 @@ static int ProtectionFlags[2][2][2] = {
},
};

static DWORD
static SIZE_T
GetRealSectionSize(PMEMORYMODULE module, PIMAGE_SECTION_HEADER section) {
DWORD size = section->SizeOfRawData;
if (size == 0) {
Expand All @@ -183,7 +202,7 @@ GetRealSectionSize(PMEMORYMODULE module, PIMAGE_SECTION_HEADER section) {
size = module->headers->OptionalHeader.SizeOfUninitializedData;
}
}
return size;
return (SIZE_T) size;
}

static BOOL
Expand Down Expand Up @@ -242,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
#endif
SECTIONFINALIZEDATA sectionData;
sectionData.address = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
sectionData.alignedAddress = ALIGN_DOWN(sectionData.address, module->pageSize);
sectionData.alignedAddress = AlignAddressDown(sectionData.address, module->pageSize);
sectionData.size = GetRealSectionSize(module, section);
sectionData.characteristics = section->Characteristics;
sectionData.last = FALSE;
Expand All @@ -251,8 +270,8 @@ FinalizeSections(PMEMORYMODULE module)
// 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);
LPVOID alignedAddress = AlignAddressDown(sectionAddress, module->pageSize);
SIZE_T 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.
Expand All @@ -263,7 +282,7 @@ FinalizeSections(PMEMORYMODULE module)
} else {
sectionData.characteristics |= section->Characteristics;
}
sectionData.size = (((uintptr_t)sectionAddress) + sectionSize) - (uintptr_t) sectionData.address;
sectionData.size = (((uintptr_t)sectionAddress) + ((uintptr_t) sectionSize)) - (uintptr_t) sectionData.address;
continue;
}

Expand Down Expand Up @@ -543,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
}

GetNativeSystemInfo(&sysInfo);
alignedImageSize = ALIGN_VALUE_UP(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
if (alignedImageSize != ALIGN_VALUE_UP(lastSectionEnd, sysInfo.dwPageSize)) {
alignedImageSize = AlignValueUp(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize)) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
Expand Down Expand Up @@ -849,7 +868,11 @@ static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(
cmp = _wcsnicmp(searchKey, resourceString->NameString, resourceString->Length);
if (cmp == 0) {
// Handle partial match
cmp = searchKeyLen - resourceString->Length;
if (searchKeyLen > resourceString->Length) {
cmp = 1;
} else if (searchKeyLen < resourceString->Length) {
cmp = -1;
}
}
if (cmp < 0) {
end = (middle != end ? middle : middle-1);
Expand Down Expand Up @@ -994,3 +1017,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
#endif
return size;
}

#ifdef TESTSUITE
#include <stdio.h>
#include <inttypes.h>

#ifndef PRIxPTR
#ifdef _WIN64
#define PRIxPTR "I64x"
#else
#define PRIxPTR "x"
#endif
#endif

static const uintptr_t AlignValueDownTests[][3] = {
{16, 16, 16},
{17, 16, 16},
{32, 16, 32},
{33, 16, 32},
#ifdef _WIN64
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
{0x12345678abcd101f, 0x1000, 0x12345678abcd1000},
#endif
{0, 0, 0},
};

static const uintptr_t AlignValueUpTests[][3] = {
{16, 16, 16},
{17, 16, 32},
{32, 16, 32},
{33, 16, 48},
#ifdef _WIN64
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
{0x12345678abcd101f, 0x1000, 0x12345678abcd2000},
#endif
{0, 0, 0},
};

BOOL MemoryModuleTestsuite() {
BOOL success = TRUE;
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
const uintptr_t* tests = AlignValueDownTests[idx];
uintptr_t value = AlignValueDown(tests[0], tests[1]);
if (value != tests[2]) {
printf("AlignValueDown failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
tests[0], tests[1], tests[2], value);
success = FALSE;
}
}
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
const uintptr_t* tests = AlignValueUpTests[idx];
uintptr_t value = AlignValueUp(tests[0], tests[1]);
if (value != tests[2]) {
printf("AlignValueUp failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
tests[0], tests[1], tests[2], value);
success = FALSE;
}
}
if (success) {
printf("OK\n");
}
return success;
}
#endif
12 changes: 10 additions & 2 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RC = rc
endif

RM = rm
CFLAGS = -Wall -g
CFLAGS = -Wall -g -DTESTSUITE
LDFLAGS =
RCFLAGS = -O coff

Expand Down Expand Up @@ -49,13 +49,20 @@ TEST_DLLS = \
test-relocate.dll \

LOADDLL_OBJ = LoadDll.o ../MemoryModule.o
TESTSUITE_OBJ = TestSuite.o ../MemoryModule.o
DLL_OBJ = SampleDLL.o SampleDLL.res

all: LoadDll.exe $(TEST_DLLS)
all: prepare_testsuite LoadDll.exe TestSuite.exe $(TEST_DLLS)

prepare_testsuite:
rm -f $(TESTSUITE_OBJ)

LoadDll.exe: $(LOADDLL_OBJ)
$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o LoadDll.exe $(LOADDLL_OBJ)

TestSuite.exe: $(TESTSUITE_OBJ)
$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -o TestSuite.exe $(TESTSUITE_OBJ)

LoadDll.o: LoadDll.cpp
$(CXX) $(CFLAGS) $(CFLAGS_EXE) -c $<

Expand All @@ -78,4 +85,5 @@ clean:
$(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ)

test: all
./runwine.sh $(PLATFORM) TestSuite.exe
./runtests.sh $(PLATFORM) "$(TEST_DLLS)"
17 changes: 17 additions & 0 deletions tests/TestSuite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#define WIN32_LEAN_AND_MEAN
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <windows.h>

extern BOOL MemoryModuleTestsuite();

int main(int argc, char* argv[])
{
if (!MemoryModuleTestsuite()) {
return 1;
}

return 0;
}
10 changes: 1 addition & 9 deletions tests/runtests.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
#!/bin/bash
PLATFORM=$1
if [ "${PLATFORM}" = "x86_64" ]; then
export WINEPREFIX=${HOME}/.wine64/
WINE=wine64
else
export WINEPREFIX=${HOME}/.wine/
WINE=wine
fi
export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.6/

read -a TEST_DLLS <<< $2

for filename in "${TEST_DLLS[@]}"
do
:
echo "Testing $filename"
${WINE} ./LoadDll.exe $filename
./runwine.sh "${PLATFORM}" ./LoadDll.exe $filename
if [ "$?" != "0" ]; then
exit 1
fi
Expand Down
15 changes: 15 additions & 0 deletions tests/runwine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
set -eu
PLATFORM=$1
shift

if [ "${PLATFORM}" = "x86_64" ]; then
export WINEPREFIX=${HOME}/.wine64/
WINE=wine64
else
export WINEPREFIX=${HOME}/.wine/
WINE=wine
fi
export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.6/

exec ${WINE} $@

0 comments on commit 221a470

Please sign in to comment.