From 5b1b9844e749a994609f4da3b40f20a338674a53 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 9 Oct 2014 07:49:28 +0000 Subject: [PATCH] Object, COFF: Cap the section contents to min(VirtualSize, SizeOfRawData) It is not useful to return the data beyond VirtualSize it's less than SizeOfRawData. An implementation detail of COFF requires the section size to be rounded up to a multiple of FileAlignment; this means that SizeOfRawData is not representative of how large the section is. Instead, we should cap it to VirtualSize when this occurs as it represents the true size of the section. Note that this is only relevant in executable files because this rounding doesn't occur in object files (and VirtualSize is always zero). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219388 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/COFFObjectFile.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index adc68ec62c5..72a6db4aab9 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -869,19 +869,33 @@ std::error_code COFFObjectFile::getSectionName(const coff_section *Sec, std::error_code COFFObjectFile::getSectionContents(const coff_section *Sec, ArrayRef &Res) const { - // PointerToRawData and SizeOfRawData won't make sense for BSS sections, don't - // do anything interesting for them. + // PointerToRawData and SizeOfRawData won't make sense for BSS sections, + // don't do anything interesting for them. assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 && "BSS sections don't have contents!"); // The only thing that we need to verify is that the contents is contained // within the file bounds. We don't need to make sure it doesn't cover other // data, as there's nothing that says that is not allowed. uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; - uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; + // SizeOfRawData and VirtualSize change what they represent depending on + // whether or not we have an executable image. + // + // For object files, SizeOfRawData contains the size of section's data; + // VirtualSize is always zero. + // + // For executables, SizeOfRawData *must* be a multiple of FileAlignment; the + // actual section size is in VirtualSize. It is possible for VirtualSize to + // be greater than SizeOfRawData; the contents past that point should be + // considered to be zero. + uint32_t DataSize; + if (Sec->VirtualSize) + DataSize = std::min(Sec->VirtualSize, Sec->SizeOfRawData); + else + DataSize = Sec->SizeOfRawData; + uintptr_t ConEnd = ConStart + DataSize; if (ConEnd > uintptr_t(Data.getBufferEnd())) return object_error::parse_failed; - Res = makeArrayRef(reinterpret_cast(ConStart), - Sec->SizeOfRawData); + Res = makeArrayRef(reinterpret_cast(ConStart), DataSize); return object_error::success; }