tools: io: do aligned read/write mapping
Align the mmap by pagesize.
Tested: Verified alignment is correct and mmap succeeds where it would
fail on a mis-aligned call.
Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I76a4f94415c9337d8ca983e24a18e3e4fc701564
diff --git a/tools/io.cpp b/tools/io.cpp
index 75677f4..cc9e7d1 100644
--- a/tools/io.cpp
+++ b/tools/io.cpp
@@ -27,16 +27,24 @@
opened = true;
}
+ /* Map based on aligned addresses - behind the scenes. */
+ const std::size_t alignedDiff = offset % sys->getpagesize();
+ const std::size_t alignedOffset = offset - alignedDiff;
+ const std::size_t alignedSize = length + alignedDiff;
+
// addr, length, prot, flags, fd, offset
- devMemMapped =
- sys->mmap(0, length, PROT_WRITE, MAP_SHARED, devMemFd, offset);
+ devMemMapped = sys->mmap(0, alignedSize, PROT_READ, MAP_SHARED, devMemFd,
+ alignedOffset);
if (devMemMapped == MAP_FAILED)
{
return false; /* but leave the file open. */
}
+ void* alignedSource =
+ static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
+
/* Copy the bytes. */
- std::memcpy(destination, devMemMapped, length);
+ std::memcpy(destination, alignedSource, length);
/* Close the map between reads for now. */
sys->munmap(devMemMapped, length);
@@ -58,16 +66,25 @@
opened = true;
}
+ /* Map based on aligned addresses - behind the scenes. */
+ const std::size_t alignedDiff = offset % sys->getpagesize();
+ const std::size_t alignedOffset = offset - alignedDiff;
+ const std::size_t alignedSize = length + alignedDiff;
+
// addr, length, prot, flags, fd, offset
- devMemMapped =
- sys->mmap(0, length, PROT_WRITE, MAP_SHARED, devMemFd, offset);
+ devMemMapped = sys->mmap(0, alignedSize, PROT_WRITE, MAP_SHARED, devMemFd,
+ alignedOffset);
+
if (devMemMapped == MAP_FAILED)
{
return false; /* but leave the file open. */
}
+ void* alignedDestination =
+ static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
+
/* Copy the bytes. */
- std::memcpy(devMemMapped, source, length);
+ std::memcpy(alignedDestination, source, length);
/* Close the map between writes for now. */
sys->munmap(devMemMapped, length);