8000 Fixed alignment of values/addresses on 64bit systems. · fancycode/MemoryModule@03cd7c9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 03cd7c9

Browse files
committed
Fixed alignment of values/addresses on 64bit systems.
1 parent de5dbce commit 03cd7c9

File tree

3 files changed

+111
-8
lines changed

3 files changed

+111
-8
lines changed

MemoryModule.c

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#pragma warning(error: 4244)
4040
// C4267: conversion from 'size_t' to 'int', possible loss of data.
4141
#pragma warning(error: 4267)
42+
43+
#define inline __inline
4244
#endif
4345

4446
#ifndef IMAGE_SIZEOF_BASE_RELOCATION
@@ -78,8 +80,21 @@ typedef struct {
7880
} SECTIONFINALIZEDATA, *PSECTIONFINALIZEDATA;
7981

8082
#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
81-
#define ALIGN_DOWN(address, alignment) (LPVOID)((uintptr_t)(address) & ~((alignment) - 1))
82-
#define ALIGN_VALUE_UP(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1))
83+
84+
static inline uintptr_t
85+
AlignValueDown(uintptr_t value, uintptr_t alignment) {
86+
return value & ~(alignment - 1);
87+
}
88+
89+
static inline LPVOID
90+
AlignAddressDown(LPVOID address, uintptr_t alignment) {
91+
return (LPVOID) AlignValueDown((uintptr_t) address, alignment);
92+
}
93+
94+
static inline size_t
95+
AlignValueUp(size_t value, size_t alignment) {
96+
return (value + alignment - 1) & ~(alignment - 1);
97+
}
8398

8499
#ifdef DEBUG_OUTPUT
85100
static void
@@ -246,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
246261
#endif
247262
SECTIONFINALIZEDATA sectionData;
248263
sectionData.address = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
249-
sectionData.alignedAddress = ALIGN_DOWN(sectionData.address, module->pageSize);
264+
sectionData.alignedAddress = AlignAddressDown(sectionData.address, module->pageSize);
250265
sectionData.size = GetRealSectionSize(module, section);
251266
sectionData.characteristics = section->Characteristics;
252267
sectionData.last = FALSE;
@@ -255,7 +270,7 @@ FinalizeSections(PMEMORYMODULE module)
255270
// loop through all sections and change access flags
256271
for (i=1; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
257272
LPVOID sectionAddress = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
258-
LPVOID alignedAddress = ALIGN_DOWN(sectionAddress, module->pageSize);
273+
LPVOID alignedAddress = AlignAddressDown(sectionAddress, module->pageSize);
259274
DWORD sectionSize = GetRealSectionSize(module, section);
260275
// Combine access flags of all sections that share a page
261276
// TODO(fancycode): We currently share flags of a trailing large section
@@ -547,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
547562
}
548563

549564
GetNativeSystemInfo(&sysInfo);
550-
alignedImageSize = ALIGN_VALUE_UP(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
551-
if (alignedImageSize != ALIGN_VALUE_UP(lastSectionEnd, sysInfo.dwPageSize)) {
565+
alignedImageSize = AlignValueUp(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
566+
if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize)) {
552567
SetLastError(ERROR_BAD_EXE_FORMAT);
553568
return NULL;
554569
}
@@ -998,3 +1013,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
9981013
#endif
9991014
return size;
10001015
}
1016+
1017+
#ifdef TESTSUITE
1018+
#include <stdio.h>
1019+
#include <inttypes.h>
1020+
1021+
#ifndef PRIxPTR
1022+
#ifdef _WIN64
1023+
#define PRIxPTR "I64x"
1024+
#else
1025+
#define PRIxPTR "x"
1026+
#endif
1027+
#endif
1028+
1029+
static const uintptr_t AlignValueDownTests[][3] = {
1030+
{16, 16, 16},
1031+
{17, 16, 16},
1032+
{32, 16, 32},
1033+
{33, 16, 32},
1034+
#ifdef _WIN64
1035+
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
1036+
{0x12345678abcd101f, 0x1000, 0x12345678abcd1000},
1037+
#endif
1038+
{0, 0, 0},
1039+
};
1040+
1041+
static const uintptr_t AlignValueUpTests[][3] = {
1042+
{16, 16, 16},
1043+
{17, 16, 32},
1044+
{32, 16, 32},
1045+
{33, 16, 48},
1046+
#ifdef _WIN64
1047+
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
1048+
{0x12345678abcd101f, 0x1000, 0x12345678abcd2000},
1049+
#endif
1050+
{0, 0, 0},
1051+
};
1052+
1053+
BOOL MemoryModuleTestsuite() {
1054+
BOOL success = TRUE;
1055+
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
1056+
const uintptr_t* tests = AlignValueDownTests[idx];
1057+
uintptr_t value = AlignValueDown(tests[0], tests[1]);
1058+
if (value != tests[2]) {
1059+
printf("AlignValueDown failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
1060+
tests[0], tests[1], tests[2], value);
1061+
success = FALSE;
1062+
}
1063+
}
1064+
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
1065+
const uintptr_t* tests = AlignValueUpTests[idx];
1066+
uintptr_t value = AlignValueUp(tests[0], tests[1]);
1067+
if (value != tests[2]) {
1068+
printf("AlignValueUp failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
1069+
tests[0], tests[1], tests[2], value);
1070+
success = FALSE;
1071+
}
1072+
}
1073+
if (success) {
1074+
printf("OK\n");
1075+
}
1076+
return success;
1077+
}
1078+
#endif

tests/Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RC = rc
1616
endif
1717

1818
RM = rm
19-
CFLAGS = -Wall -g
19+
CFLAGS = -Wall -g -DTESTSUITE
2020
LDFLAGS =
2121
RCFLAGS = -O coff
2222

@@ -49,13 +49,20 @@ TEST_DLLS = \
4949
test-relocate.dll \
5050

5151
LOADDLL_OBJ = LoadDll.o ../MemoryModule.o
52+
TESTSUITE_OBJ = TestSuite.o ../MemoryModule.o
5253
DLL_OBJ = SampleDLL.o SampleDLL.res
5354

54-
all: LoadDll.exe $(TEST_DLLS)
55+
all: prepare_testsuite LoadDll.exe TestSuite.exe $(TEST_DLLS)
56+
57+
prepare_testsuite:
58+
rm -f $(TESTSUITE_OBJ)
5559

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

63+
TestSuite.exe: $(TESTSUITE_OBJ)
64+
$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -o TestSuite.exe $(TESTSUITE_OBJ)
65+
5966
LoadDll.o: LoadDll.cpp
6067
$(CXX) $(CFLAGS) $(CFLAGS_EXE) -c $<
6168

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

8087
test: all
88+
./TestSuite.exe
8189
./runtests.sh $(PLATFORM) "$(TEST_DLLS)"

tests/TestSuite.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#define WIN32_LEAN_AND_MEAN
2+
#ifndef _CRT_SECURE_NO_WARNINGS
3+
#define _CRT_SECURE_NO_WARNINGS
4+
#endif
5+
6+
#include <windows.h>
7+
8+
extern BOOL MemoryModuleTestsuite();
9+
10+
int main(int argc, char* argv[])
11+
{
12+
if (!MemoryModuleTestsuite()) {
13+
return 1;
14+
}
15+
16+
return 0;
17+
}

0 commit comments

Comments
 (0)
0