From 6d191534f63b0ece222e2d6e418144b123c81c0c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 19 Mar 2014 04:47:47 +0000 Subject: Object: Provide a richer means of describing auxiliary symbols The current state of affairs has auxiliary symbols described as a big bag of bytes. This is less than satisfying, it detracts from the YAML file as being human readable. Instead, allow for symbols to optionally contain their auxiliary data. This allows us to have a much higher level way of describing things like weak symbols, function definitions and section definitions. This depends on D3105. Differential Revision: http://llvm-reviews.chandlerc.com/D3092 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204214 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2coff.cpp | 82 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 8 deletions(-) (limited to 'tools/yaml2obj') diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index c757eb64fb..a0ede246bd 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" @@ -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) @@ -253,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. -- cgit v1.2.3