diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/llvm-nm/llvm-nm.cpp | 3 | ||||
-rw-r--r-- | tools/llvm-objdump/llvm-objdump.cpp | 3 | ||||
-rw-r--r-- | tools/llvm-readobj/COFFDumper.cpp | 23 | ||||
-rw-r--r-- | tools/obj2yaml/coff2yaml.cpp | 112 | ||||
-rw-r--r-- | tools/yaml2obj/yaml2coff.cpp | 82 |
5 files changed, 192 insertions, 31 deletions
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 100a1f20a1..22e019a8a5 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -344,8 +344,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { return 'i'; // Check for section symbol. - else if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && - Symb->Value == 0) + else if (Symb->isSectionDefinition()) return 's'; } diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 3f871471bc..f5328a959e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -663,8 +663,7 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) { if (aux_count--) { // Figure out which type of aux this is. - if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC - && symbol->Value == 0) { // Section definition. + if (symbol->isSectionDefinition()) { // Section definition. const coff_aux_section_definition *asd; if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd))) return; diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index d2275f0aab..cd40da7d6c 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -946,12 +946,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols); for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) { - if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && - Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION && - Symbol->SectionNumber != COFF::IMAGE_SYM_DEBUG && - Symbol->SectionNumber != COFF::IMAGE_SYM_ABSOLUTE && - Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED) { + if (Symbol->isFunctionDefinition()) { const coff_aux_function_definition *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; @@ -963,11 +958,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); W.printBinary("Unused", makeArrayRef(Aux->Unused)); - } else if ( - Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || - (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - Symbol->SectionNumber == COFF::IMAGE_SYM_UNDEFINED && - Symbol->Value == 0)) { + } else if (Symbol->isWeakExternal()) { const coff_aux_weak_external *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; @@ -987,7 +978,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { makeArrayRef(WeakExternalCharacteristics)); W.printBinary("Unused", makeArrayRef(Aux->Unused)); - } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) { + } else if (Symbol->isFileRecord()) { const coff_aux_file_record *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; @@ -995,11 +986,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { DictScope AS(W, "AuxFileRecord"); W.printString("FileName", StringRef(Aux->FileName)); - // C++/CLI creates external ABS symbols for non-const appdomain globals. - // These are also followed by an auxiliary section definition. - } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC || - (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && - Symbol->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)) { + } else if (Symbol->isSectionDefinition()) { const coff_aux_section_definition *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; @@ -1026,7 +1013,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("AssocSection", AssocName, Aux->Number); } - } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) { + } else if (Symbol->isCLRToken()) { const coff_aux_clr_token *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 6cf79aeabc..b003029407 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -78,6 +78,61 @@ void COFFDumper::dumpSections(unsigned NumSections) { } } +static void +dumpFunctionDefinition(COFFYAML::Symbol *Sym, + const object::coff_aux_function_definition *ObjFD) { + COFF::AuxiliaryFunctionDefinition YAMLFD; + YAMLFD.TagIndex = ObjFD->TagIndex; + YAMLFD.TotalSize = ObjFD->TotalSize; + YAMLFD.PointerToLinenumber = ObjFD->PointerToLinenumber; + YAMLFD.PointerToNextFunction = ObjFD->PointerToNextFunction; + + Sym->FunctionDefinition = YAMLFD; +} + +static void +dumpbfAndEfLineInfo(COFFYAML::Symbol *Sym, + const object::coff_aux_bf_and_ef_symbol *ObjBES) { + COFF::AuxiliarybfAndefSymbol YAMLAAS; + YAMLAAS.Linenumber = ObjBES->Linenumber; + YAMLAAS.PointerToNextFunction = ObjBES->PointerToNextFunction; + + Sym->bfAndefSymbol = YAMLAAS; +} + +static void dumpWeakExternal(COFFYAML::Symbol *Sym, + const object::coff_aux_weak_external *ObjWE) { + COFF::AuxiliaryWeakExternal YAMLWE; + YAMLWE.TagIndex = ObjWE->TagIndex; + YAMLWE.Characteristics = ObjWE->Characteristics; + + Sym->WeakExternal = YAMLWE; +} + +static void +dumpSectionDefinition(COFFYAML::Symbol *Sym, + const object::coff_aux_section_definition *ObjSD) { + COFF::AuxiliarySectionDefinition YAMLASD; + YAMLASD.Length = ObjSD->Length; + YAMLASD.NumberOfRelocations = ObjSD->NumberOfRelocations; + YAMLASD.NumberOfLinenumbers = ObjSD->NumberOfLinenumbers; + YAMLASD.CheckSum = ObjSD->CheckSum; + YAMLASD.Number = ObjSD->Number; + YAMLASD.Selection = ObjSD->Selection; + + Sym->SectionDefinition = YAMLASD; +} + +static void +dumpCLRTokenDefinition(COFFYAML::Symbol *Sym, + const object::coff_aux_clr_token *ObjCLRToken) { + COFF::AuxiliaryCLRToken YAMLCLRToken; + YAMLCLRToken.AuxType = ObjCLRToken->AuxType; + YAMLCLRToken.SymbolTableIndex = ObjCLRToken->SymbolTableIndex; + + Sym->CLRToken = YAMLCLRToken; +} + void COFFDumper::dumpSymbols(unsigned NumSymbols) { std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols; for (const auto &S : Obj.symbols()) { @@ -90,7 +145,62 @@ void COFFDumper::dumpSymbols(unsigned NumSymbols) { Sym.Header.Value = Symbol->Value; Sym.Header.SectionNumber = Symbol->SectionNumber; Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; - Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol)); + + if (Symbol->NumberOfAuxSymbols > 0) { + ArrayRef<uint8_t> AuxData = Obj.getSymbolAuxData(Symbol); + if (Symbol->isFunctionDefinition()) { + // This symbol represents a function definition. + assert(Symbol->NumberOfAuxSymbols == 1 && + "Expected a single aux symbol to describe this function!"); + + const object::coff_aux_function_definition *ObjFD = + reinterpret_cast<const object::coff_aux_function_definition *>( + AuxData.data()); + dumpFunctionDefinition(&Sym, ObjFD); + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION) { + // This symbol describes function line number information. + assert(Symbol->NumberOfAuxSymbols == 1 && + "Exepected a single aux symbol to describe this section!"); + + const object::coff_aux_bf_and_ef_symbol *ObjBES = + reinterpret_cast<const object::coff_aux_bf_and_ef_symbol *>( + AuxData.data()); + dumpbfAndEfLineInfo(&Sym, ObjBES); + } else if (Symbol->isWeakExternal()) { + // This symbol represents a weak external definition. + assert(Symbol->NumberOfAuxSymbols == 1 && + "Exepected a single aux symbol to describe this section!"); + + const object::coff_aux_weak_external *ObjWE = + reinterpret_cast<const object::coff_aux_weak_external *>( + AuxData.data()); + dumpWeakExternal(&Sym, ObjWE); + } else if (Symbol->isFileRecord()) { + // This symbol represents a file record. + Sym.File = StringRef(reinterpret_cast<const char *>(AuxData.data()), + Symbol->NumberOfAuxSymbols * COFF::SymbolSize); + } else if (Symbol->isSectionDefinition()) { + // This symbol represents a section definition. + assert(Symbol->NumberOfAuxSymbols == 1 && + "Expected a single aux symbol to describe this section!"); + + const object::coff_aux_section_definition *ObjSD = + reinterpret_cast<const object::coff_aux_section_definition *>( + AuxData.data()); + dumpSectionDefinition(&Sym, ObjSD); + } else if (Symbol->isCLRToken()) { + // This symbol represents a CLR token definition. + assert(Symbol->NumberOfAuxSymbols == 1 && + "Expected a single aux symbol to describe this CLR Token"); + + const object::coff_aux_clr_token *ObjCLRToken = + reinterpret_cast<const object::coff_aux_clr_token *>( + AuxData.data()); + dumpCLRTokenDefinition(&Sym, ObjCLRToken); + } else { + llvm_unreachable("Unhandled auxiliary symbol!"); + } + } Symbols.push_back(Sym); } } 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<COFFYAML::Symbol>::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<value_type> binary_le(value_type V) { return binary_le_impl<value_type>(V); } +template <size_t NumBytes> +struct zeros_impl { + zeros_impl() {} +}; + +template <size_t NumBytes> +raw_ostream &operator<<(raw_ostream &OS, const zeros_impl<NumBytes> &) { + char Buffer[NumBytes]; + memset(Buffer, 0, sizeof(Buffer)); + OS.write(Buffer, sizeof(Buffer)); + return OS; +} + +template <typename T> +zeros_impl<sizeof(T)> zeros(const T &) { + return zeros_impl<sizeof(T)>(); +} + 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. |