def _translate_entry(self, offset: int) -> Tuple[int, int]: """Translates a specific offset based on paging tables. Returns the translated entry value """ # Setup the entry and how far we are through the offset # Position maintains the number of bits left to process # We or with 0x1 to ensure our page_map_offset is always valid position = self._initial_position entry = self._initial_entry # Run through the offset in various chunks for (name, size, large_page) in self._structure: # Check we're valid if not self._page_is_valid(entry): raise exceptions.PagedInvalidAddressException(self.name, offset, position + 1, entry, "Page Fault at entry " + hex(entry) + " in table " + name) # Check if we're a large page if large_page and (entry & (1 << 7)): # We're a large page, the rest is finished below # If we want to implement PSE-36, it would need to be done here break # Figure out how much of the offset we should be using start = position position -= size index = self._mask(offset, start, position + 1) >> (position + 1) # Grab the base address of the table we'll be getting the next entry from base_address = self._mask(entry, self._maxphyaddr - 1, size + self._index_shift) table = self._get_valid_table(base_address) if table is None: raise exceptions.PagedInvalidAddressException(self.name, offset, position + 1, entry, "Page Fault at entry " + hex(entry) + " in table " + name) # Read the data for the next entry entry_data = table[(index << self._index_shift):(index << self._index_shift) + self._entry_size] if INTEL_TRANSLATION_DEBUGGING: vollog.log( constants.LOGLEVEL_VVVV, "Entry {} at index {} gives data {} as {}".format( hex(entry), hex(index), hex(struct.unpack(self._entry_format, entry_data)[0]), name)) # Read out the new entry from memory entry, = struct.unpack(self._entry_format, entry_data) return entry, position
def _translate(self, offset: int) -> Tuple[int, int, str]: """Translates a specific offset based on paging tables. Returns the translated offset, the contiguous pagesize that the translated address lives in and the layer_name that the address lives in """ entry, position = self._translate_entry(offset) # Now we're done if not self._page_is_valid(entry): raise exceptions.PagedInvalidAddressException(self.name, offset, position + 1, entry, "Page Fault at entry {} in page entry".format(hex(entry))) page = self._mask(entry, self._maxphyaddr - 1, position + 1) | self._mask(offset, position, 0) return page, 1 << (position + 1), self._base_layer