llvm.org GIT mirror llvm / a9d6942
yaml2obj, COFF: Correctly calculate SizeOfImage and SizeOfHeaders SizeOfHeaders must be aligned to the FileAlignment. SizeOfImage must be at least the SizeOfHeaders aligned to the SectionAlignment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222030 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
1 changed file(s) with 16 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
143143 static bool layoutOptionalHeader(COFFParser &CP) {
144144 if (!CP.isPE())
145145 return true;
146 unsigned PEHeaderSize = CP.is64Bit() ? sizeof(object::pe32plus_header)
147 : sizeof(object::pe32_header);
146148 CP.Obj.Header.SizeOfOptionalHeader =
147 (CP.is64Bit() ? sizeof(object::pe32plus_header)
148 : sizeof(object::pe32_header)) +
149 (sizeof(object::data_directory) * (COFF::NUM_DATA_DIRECTORIES + 1));
149 PEHeaderSize +
150 sizeof(object::data_directory) * (COFF::NUM_DATA_DIRECTORIES + 1);
150151 return true;
151152 }
152153
280281 }
281282
282283 template
283 static void initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) {
284 static uint32_t initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) {
284285 memset(Header, 0, sizeof(*Header));
285286 Header->Magic = Magic;
286287 Header->SectionAlignment = CP.Obj.OptionalHeader->Header.SectionAlignment;
288 Header->FileAlignment = CP.Obj.OptionalHeader->Header.FileAlignment;
287289 uint32_t SizeOfCode = 0, SizeOfInitializedData = 0,
288290 SizeOfUninitializedData = 0;
289291 uint32_t SizeOfHeaders = RoundUpToAlignment(
290 CP.SectionTableStart + CP.SectionTableSize, Header->SectionAlignment);
291 uint32_t SizeOfImage = SizeOfHeaders;
292 CP.SectionTableStart + CP.SectionTableSize, Header->FileAlignment);
293 uint32_t SizeOfImage =
294 RoundUpToAlignment(SizeOfHeaders, Header->SectionAlignment);
295 uint32_t BaseOfData = 0;
292296 for (const COFFYAML::Section &S : CP.Obj.Sections) {
293297 if (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_CODE)
294298 SizeOfCode += S.Header.SizeOfRawData;
297301 if (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
298302 SizeOfUninitializedData += S.Header.SizeOfRawData;
299303 if (S.Name.equals(".text"))
300 Header->BaseOfCode = S.Header.VirtualAddress; // RVA
304 Header->BaseOfCode = S.Header.VirtualAddress; // RVA
305 else if (S.Name.equals(".data"))
306 BaseOfData = S.Header.VirtualAddress; // RVA
301307 if (S.Header.VirtualAddress)
302308 SizeOfImage +=
303309 RoundUpToAlignment(S.Header.VirtualSize, Header->SectionAlignment);
308314 Header->AddressOfEntryPoint =
309315 CP.Obj.OptionalHeader->Header.AddressOfEntryPoint; // RVA
310316 Header->ImageBase = CP.Obj.OptionalHeader->Header.ImageBase;
311 Header->FileAlignment = CP.Obj.OptionalHeader->Header.FileAlignment;
312317 Header->MajorOperatingSystemVersion =
313318 CP.Obj.OptionalHeader->Header.MajorOperatingSystemVersion;
314319 Header->MinorOperatingSystemVersion =
330335 Header->SizeOfHeapReserve = CP.Obj.OptionalHeader->Header.SizeOfHeapReserve;
331336 Header->SizeOfHeapCommit = CP.Obj.OptionalHeader->Header.SizeOfHeapCommit;
332337 Header->NumberOfRvaAndSize = COFF::NUM_DATA_DIRECTORIES + 1;
338 return BaseOfData;
333339 }
334340
335341 static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
386392 OS.write(reinterpret_cast(&PEH), sizeof(PEH));
387393 } else {
388394 object::pe32_header PEH;
389 initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH);
395 uint32_t BaseOfData = initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH);
396 PEH.BaseOfData = BaseOfData;
390397 OS.write(reinterpret_cast(&PEH), sizeof(PEH));
391398 }
392399 for (const Optional &DD :