39
39
#pragma warning(error: 4244)
40
40
// C4267: conversion from 'size_t' to 'int', possible loss of data.
41
41
#pragma warning(error: 4267)
42
+
43
+ #define inline __inline
42
44
#endif
43
45
44
46
#ifndef IMAGE_SIZEOF_BASE_RELOCATION
@@ -78,8 +80,21 @@ typedef struct {
78
80
} SECTIONFINALIZEDATA , * PSECTIONFINALIZEDATA ;
79
81
80
82
#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
+ }
83
98
84
99
#ifdef DEBUG_OUTPUT
85
100
static void
@@ -246,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
246
261
#endif
247
262
SECTIONFINALIZEDATA sectionData ;
248
263
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 );
250
265
sectionData .size = GetRealSectionSize (module , section );
251
266
sectionData .characteristics = section -> Characteristics ;
252
267
sectionData .last = FALSE;
@@ -255,7 +270,7 @@ FinalizeSections(PMEMORYMODULE module)
255
270
// loop through all sections and change access flags
256
271
for (i = 1 ; i < module -> headers -> FileHeader .NumberOfSections ; i ++ , section ++ ) {
257
272
LPVOID sectionAddress = (LPVOID )((uintptr_t )section -> Misc .PhysicalAddress | imageOffset );
258
- LPVOID alignedAddress = ALIGN_DOWN (sectionAddress , module -> pageSize );
273
+ LPVOID alignedAddress = AlignAddressDown (sectionAddress , module -> pageSize );
259
274
DWORD sectionSize = GetRealSectionSize (module , section );
260
275
// Combine access flags of all sections that share a page
261
276
// TODO(fancycode): We currently share flags of a trailing large section
@@ -547,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
547
562
}
548
563
549
564
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 )) {
552
567
SetLastError (ERROR_BAD_EXE_FORMAT );
553
568
return NULL ;
554
569
}
@@ -998,3 +1013,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
998
1013
#endif
999
1014
return size ;
1000
1015
}
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
0 commit comments