X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fyaml2obj%2Fyaml2coff.cpp;h=c772db9a8e8055fbb1db28b98aa273031220750d;hb=7cba2a973f79861d810a8bf927fd78b352fb712f;hp=d800b90791cffdbaaf2ff87f37fe9512dc892759;hpb=63958fba58716ed435563321944f7d4663d2ee2d;p=oota-llvm.git diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index d800b90791c..c772db9a8e8 100644 --- a/tools/yaml2obj/yaml2coff.cpp +++ b/tools/yaml2obj/yaml2coff.cpp @@ -14,6 +14,7 @@ #include "yaml2obj.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" @@ -32,7 +33,7 @@ struct COFFParser { COFFParser(COFFYAML::Object &Obj) : Obj(Obj) { // A COFF string table always starts with a 4 byte size field. Offsets into // it include this size, so allocate it now. - StringTable.append(4, 0); + StringTable.append(4, char(0)); } bool parseSections() { @@ -153,13 +154,22 @@ static bool layoutCOFF(COFFParser &CP) { for (std::vector::iterator i = CP.Obj.Symbols.begin(), e = CP.Obj.Symbols.end(); i != e; ++i) { - unsigned AuxBytes = i->AuxiliaryData.binary_size(); - if (AuxBytes % COFF::SymbolSize != 0) { - errs() << "AuxiliaryData size not a multiple of symbol size!\n"; - return false; - } - i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize; - NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; + uint32_t NumberOfAuxSymbols = 0; + if (i->FunctionDefinition) + NumberOfAuxSymbols += 1; + if (i->bfAndefSymbol) + NumberOfAuxSymbols += 1; + if (i->WeakExternal) + NumberOfAuxSymbols += 1; + if (!i->File.empty()) + NumberOfAuxSymbols += + (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize; + if (i->SectionDefinition) + NumberOfAuxSymbols += 1; + if (i->CLRToken) + NumberOfAuxSymbols += 1; + i->Header.NumberOfAuxSymbols = NumberOfAuxSymbols; + NumberOfSymbols += 1 + NumberOfAuxSymbols; } // Store all the allocated start addresses in the header. @@ -194,6 +204,24 @@ binary_le_impl binary_le(value_type V) { return binary_le_impl(V); } +template +struct zeros_impl { + zeros_impl() {} +}; + +template +raw_ostream &operator<<(raw_ostream &OS, const zeros_impl &) { + char Buffer[NumBytes]; + memset(Buffer, 0, sizeof(Buffer)); + OS.write(Buffer, sizeof(Buffer)); + return OS; +} + +template +zeros_impl zeros(const T &) { + return zeros_impl(); +} + bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS << binary_le(CP.Obj.Header.Machine) << binary_le(CP.Obj.Header.NumberOfSections) @@ -219,15 +247,25 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.Characteristics); } + unsigned CurSymbol = 0; + StringMap SymbolTableIndexMap; + for (std::vector::iterator I = CP.Obj.Symbols.begin(), + E = CP.Obj.Symbols.end(); + I != E; ++I) { + SymbolTableIndexMap[I->Name] = CurSymbol; + CurSymbol += 1 + I->Header.NumberOfAuxSymbols; + } + // Output section data. for (std::vector::iterator i = CP.Obj.Sections.begin(), e = CP.Obj.Sections.end(); i != e; ++i) { i->SectionData.writeAsBinary(OS); for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) { - const COFF::relocation &R = i->Relocations[I2]; + const COFFYAML::Relocation &R = i->Relocations[I2]; + uint32_t SymbolTableIndex = SymbolTableIndexMap[R.SymbolName]; OS << binary_le(R.VirtualAddress) - << binary_le(R.SymbolTableIndex) + << binary_le(SymbolTableIndex) << binary_le(R.Type); } } @@ -243,7 +281,45 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.Type) << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); - i->AuxiliaryData.writeAsBinary(OS); + + if (i->FunctionDefinition) + OS << binary_le(i->FunctionDefinition->TagIndex) + << binary_le(i->FunctionDefinition->TotalSize) + << binary_le(i->FunctionDefinition->PointerToLinenumber) + << binary_le(i->FunctionDefinition->PointerToNextFunction) + << zeros(i->FunctionDefinition->unused); + if (i->bfAndefSymbol) + OS << zeros(i->bfAndefSymbol->unused1) + << binary_le(i->bfAndefSymbol->Linenumber) + << zeros(i->bfAndefSymbol->unused2) + << binary_le(i->bfAndefSymbol->PointerToNextFunction) + << zeros(i->bfAndefSymbol->unused3); + if (i->WeakExternal) + OS << binary_le(i->WeakExternal->TagIndex) + << binary_le(i->WeakExternal->Characteristics) + << zeros(i->WeakExternal->unused); + if (!i->File.empty()) { + uint32_t NumberOfAuxRecords = + (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize; + uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::SymbolSize; + uint32_t NumZeros = NumberOfAuxBytes - i->File.size(); + OS.write(i->File.data(), i->File.size()); + for (uint32_t Padding = 0; Padding < NumZeros; ++Padding) + OS.write(0); + } + if (i->SectionDefinition) + OS << binary_le(i->SectionDefinition->Length) + << binary_le(i->SectionDefinition->NumberOfRelocations) + << binary_le(i->SectionDefinition->NumberOfLinenumbers) + << binary_le(i->SectionDefinition->CheckSum) + << binary_le(i->SectionDefinition->Number) + << binary_le(i->SectionDefinition->Selection) + << zeros(i->SectionDefinition->unused); + if (i->CLRToken) + OS << binary_le(i->CLRToken->AuxType) + << zeros(i->CLRToken->unused1) + << binary_le(i->CLRToken->SymbolTableIndex) + << zeros(i->CLRToken->unused2); } // Output string table. @@ -251,8 +327,7 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { return true; } -int yaml2coff(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf) { - yaml::Input YIn(Buf->getBuffer()); +int yaml2coff(yaml::Input &YIn, raw_ostream &Out) { COFFYAML::Object Doc; YIn >> Doc; if (YIn.error()) {