X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fyaml2obj%2Fyaml2coff.cpp;h=61d985192552be60b9dd8818c925118327c35710;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=2c71988bad905b332ce04ac19158058397b11af9;hpb=237544b16d9d99496395f2250547e4eda1d43c95;p=oota-llvm.git diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index 2c71988bad9..61d98519255 100644 --- a/tools/yaml2obj/yaml2coff.cpp +++ b/tools/yaml2obj/yaml2coff.cpp @@ -13,13 +13,13 @@ //===----------------------------------------------------------------------===// #include "yaml2obj.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Object/COFFYAML.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/COFFYAML.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -144,13 +144,18 @@ struct COFFParser { static bool layoutOptionalHeader(COFFParser &CP) { if (!CP.isPE()) return true; + unsigned PEHeaderSize = CP.is64Bit() ? sizeof(object::pe32plus_header) + : sizeof(object::pe32_header); CP.Obj.Header.SizeOfOptionalHeader = - (CP.is64Bit() ? sizeof(object::pe32plus_header) - : sizeof(object::pe32_header)) + - (sizeof(object::data_directory) * (COFF::NUM_DATA_DIRECTORIES + 1)); + PEHeaderSize + + sizeof(object::data_directory) * (COFF::NUM_DATA_DIRECTORIES + 1); return true; } +namespace { +enum { DOSStubSize = 128 }; +} + // Take a CP and assign addresses and sizes to everything. Returns false if the // layout is not valid to do. static bool layoutCOFF(COFFParser &CP) { @@ -158,6 +163,8 @@ static bool layoutCOFF(COFFParser &CP) { // optional header. CP.SectionTableStart = CP.getHeaderSize() + CP.Obj.Header.SizeOfOptionalHeader; + if (CP.isPE()) + CP.SectionTableStart += DOSStubSize + sizeof(COFF::PEMagic); CP.SectionTableSize = COFF::SectionSize * CP.Obj.Sections.size(); uint32_t CurrentSectionDataOffset = @@ -246,10 +253,7 @@ binary_le_impl binary_le(value_type V) { return binary_le_impl(V); } -template -struct zeros_impl { - zeros_impl() {} -}; +template struct zeros_impl {}; template raw_ostream &operator<<(raw_ostream &OS, const zeros_impl &) { @@ -275,21 +279,24 @@ raw_ostream &operator<<(raw_ostream &OS, const num_zeros_impl &NZI) { return OS; } -num_zeros_impl num_zeros(size_t N) { +static num_zeros_impl num_zeros(size_t N) { num_zeros_impl NZI(N); return NZI; } template -static void initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { +static uint32_t initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { memset(Header, 0, sizeof(*Header)); Header->Magic = Magic; Header->SectionAlignment = CP.Obj.OptionalHeader->Header.SectionAlignment; + Header->FileAlignment = CP.Obj.OptionalHeader->Header.FileAlignment; uint32_t SizeOfCode = 0, SizeOfInitializedData = 0, SizeOfUninitializedData = 0; uint32_t SizeOfHeaders = RoundUpToAlignment( - CP.SectionTableStart + CP.SectionTableSize, Header->SectionAlignment); - uint32_t SizeOfImage = SizeOfHeaders; + CP.SectionTableStart + CP.SectionTableSize, Header->FileAlignment); + uint32_t SizeOfImage = + RoundUpToAlignment(SizeOfHeaders, Header->SectionAlignment); + uint32_t BaseOfData = 0; for (const COFFYAML::Section &S : CP.Obj.Sections) { if (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_CODE) SizeOfCode += S.Header.SizeOfRawData; @@ -298,7 +305,9 @@ static void initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { if (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) SizeOfUninitializedData += S.Header.SizeOfRawData; if (S.Name.equals(".text")) - Header->BaseOfCode = S.Header.VirtualAddress; // RVA + Header->BaseOfCode = S.Header.VirtualAddress; // RVA + else if (S.Name.equals(".data")) + BaseOfData = S.Header.VirtualAddress; // RVA if (S.Header.VirtualAddress) SizeOfImage += RoundUpToAlignment(S.Header.VirtualSize, Header->SectionAlignment); @@ -309,7 +318,6 @@ static void initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { Header->AddressOfEntryPoint = CP.Obj.OptionalHeader->Header.AddressOfEntryPoint; // RVA Header->ImageBase = CP.Obj.OptionalHeader->Header.ImageBase; - Header->FileAlignment = CP.Obj.OptionalHeader->Header.FileAlignment; Header->MajorOperatingSystemVersion = CP.Obj.OptionalHeader->Header.MajorOperatingSystemVersion; Header->MinorOperatingSystemVersion = @@ -331,6 +339,7 @@ static void initializeOptionalHeader(COFFParser &CP, uint16_t Magic, T Header) { Header->SizeOfHeapReserve = CP.Obj.OptionalHeader->Header.SizeOfHeapReserve; Header->SizeOfHeapCommit = CP.Obj.OptionalHeader->Header.SizeOfHeapCommit; Header->NumberOfRvaAndSize = COFF::NUM_DATA_DIRECTORIES + 1; + return BaseOfData; } static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { @@ -347,13 +356,13 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { // 0x40. DH.AddressOfRelocationTable = sizeof(DH); // This is the address of the PE signature. - DH.AddressOfNewExeHeader = 128; + DH.AddressOfNewExeHeader = DOSStubSize; // Write out our DOS stub. OS.write(reinterpret_cast(&DH), sizeof(DH)); // Write padding until we reach the position of where our PE signature // should live. - OS << num_zeros(DH.AddressOfNewExeHeader - sizeof(DH)); + OS << num_zeros(DOSStubSize - sizeof(DH)); // Write out the PE signature. OS.write(COFF::PEMagic, sizeof(COFF::PEMagic)); } @@ -387,7 +396,8 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS.write(reinterpret_cast(&PEH), sizeof(PEH)); } else { object::pe32_header PEH; - initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH); + uint32_t BaseOfData = initializeOptionalHeader(CP, COFF::PE32Header::PE32, &PEH); + PEH.BaseOfData = BaseOfData; OS.write(reinterpret_cast(&PEH), sizeof(PEH)); } for (const Optional &DD : @@ -404,6 +414,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS << zeros(uint32_t(0)); } + assert(OS.tell() == CP.SectionTableStart); // Output section table. for (std::vector::iterator i = CP.Obj.Sections.begin(), e = CP.Obj.Sections.end(); @@ -419,6 +430,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.NumberOfLineNumbers) << binary_le(i->Header.Characteristics); } + assert(OS.tell() == CP.SectionTableStart + CP.SectionTableSize); unsigned CurSymbol = 0; StringMap SymbolTableIndexMap; @@ -433,8 +445,10 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { for (const COFFYAML::Section &S : CP.Obj.Sections) { if (!S.Header.SizeOfRawData) continue; + assert(S.Header.PointerToRawData >= OS.tell()); OS << num_zeros(S.Header.PointerToRawData - OS.tell()); S.SectionData.writeAsBinary(OS); + assert(S.Header.SizeOfRawData >= S.SectionData.binary_size()); OS << num_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size()); for (const COFFYAML::Relocation &R : S.Relocations) { uint32_t SymbolTableIndex = SymbolTableIndexMap[R.SymbolName];