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
85100static 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
0 commit comments