@@ -195,21 +195,45 @@ def show_mapinfo(self):
195195 def get_lib_base (self , filename : str ) -> int :
196196 return next ((s for s , _ , _ , info , _ in self .map_info if os .path .split (info )[1 ] == filename ), - 1 )
197197
198- def align (self , addr : int , alignment : int = None ) -> int :
199- """Round up to nearest alignment.
198+ def align (self , value : int , alignment : int = None ) -> int :
199+ """Align a value down to the specified alignment boundary .
200200
201201 Args:
202- addr: address to align
203- alignment: alignment granularity, must be a power of 2
202+ value: a value to align
203+ alignment: alignment boundary; must be a power of 2. if not specified
204+ value will be aligned to page size
205+
206+ Returns: aligned value
207+ """
208+
209+ if alignment is None :
210+ alignment = self .pagesize
211+
212+ # make sure alignment is a power of 2
213+ assert alignment & (alignment - 1 ) == 0
214+
215+ # round down to nearest alignment
216+ return value & ~ (alignment - 1 )
217+
218+ def align_up (self , value : int , alignment : int = None ) -> int :
219+ """Align a value up to the specified alignment boundary.
220+
221+ Args:
222+ value: value to align
223+ alignment: alignment boundary; must be a power of 2. if not specified
224+ value will be aligned to page size
225+
226+ Returns: aligned value
204227 """
205228
206229 if alignment is None :
207230 alignment = self .pagesize
208231
209- # rounds up to nearest alignment
210- mask = self . max_mem_addr & - alignment
232+ # make sure alignment is a power of 2
233+ assert alignment & ( alignment - 1 ) == 0
211234
212- return (addr + (alignment - 1 )) & mask
235+ # round up to nearest alignment
236+ return (value + alignment - 1 ) & ~ (alignment - 1 )
213237
214238 def save (self ):
215239 """Save entire memory content.
@@ -431,7 +455,7 @@ def find_free_space(self, size: int, minaddr: int = None, maxaddr: int = None, a
431455 gaps = zip (gaps_lbounds , gaps_ubounds )
432456
433457 for lbound , ubound in gaps :
434- addr = self .align (lbound , align )
458+ addr = self .align_up (lbound , align )
435459 end = addr + size
436460
437461 # is aligned range within gap and satisfying min / max requirements?
@@ -457,18 +481,19 @@ def map_anywhere(self, size: int, minaddr: int = None, maxaddr: int = None, alig
457481 if align is None :
458482 align = self .pagesize
459483
484+ size = self .align_up (size )
460485 addr = self .find_free_space (size , minaddr , maxaddr , align )
461486
462- self .map (addr , self . align ( size ) , perms , info )
487+ self .map (addr , size , perms , info )
463488
464489 return addr
465490
466491 def protect (self , addr : int , size : int , perms ):
467492 # mask off perms bits that are not supported by unicorn
468493 perms &= UC_PROT_ALL
469494
470- aligned_address = addr & ~ ( self .pagesize - 1 )
471- aligned_size = self .align ((addr & (self .pagesize - 1 )) + size )
495+ aligned_address = self .align ( addr )
496+ aligned_size = self .align_up ((addr & (self .pagesize - 1 )) + size )
472497
473498 self .ql .uc .mem_protect (aligned_address , aligned_size , perms )
474499 self .change_mapinfo (aligned_address , aligned_address + aligned_size , mem_p = perms )
@@ -590,7 +615,7 @@ def alloc(self, size: int) -> int:
590615 # is new chunk going to exceed currently allocated heap space?
591616 # in case it does, allocate additional heap space
592617 if self .current_use + size > self .current_alloc :
593- real_size = self .ql .mem .align (size )
618+ real_size = self .ql .mem .align_up (size )
594619
595620 # if that additional allocation is going to exceed heap upper bound, fail
596621 if self .start_address + self .current_use + real_size > self .end_address :
0 commit comments