diff --git a/llvm/include/llvm/ObjectYAML/ObjectYAML.h b/llvm/include/llvm/ObjectYAML/ObjectYAML.h --- a/llvm/include/llvm/ObjectYAML/ObjectYAML.h +++ b/llvm/include/llvm/ObjectYAML/ObjectYAML.h @@ -15,6 +15,7 @@ #include "llvm/ObjectYAML/MachOYAML.h" #include "llvm/ObjectYAML/MinidumpYAML.h" #include "llvm/ObjectYAML/WasmYAML.h" +#include "llvm/ObjectYAML/XCOFFYAML.h" #include "llvm/Support/YAMLTraits.h" #include @@ -31,6 +32,7 @@ std::unique_ptr FatMachO; std::unique_ptr Minidump; std::unique_ptr Wasm; + std::unique_ptr Xcoff; }; template <> struct MappingTraits { diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h --- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h +++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h @@ -23,32 +23,62 @@ llvm::yaml::Hex16 Magic; uint16_t NumberOfSections; int32_t TimeStamp; - llvm::yaml::Hex32 SymbolTableOffset; // File offset to symbol table. - int32_t NumberOfSymTableEntries; + llvm::yaml::Hex64 SymbolTableOffset; + uint32_t NumberOfSymTableEntries; uint16_t AuxHeaderSize; llvm::yaml::Hex16 Flags; }; +struct Relocation { + llvm::yaml::Hex64 VirtualAddress; + llvm::yaml::Hex64 SymbolIndex; + llvm::yaml::Hex8 Info; + llvm::yaml::Hex8 Type; +}; + +struct Section { + StringRef SectionName; + llvm::yaml::Hex64 Address; + llvm::yaml::Hex64 Size; + llvm::yaml::Hex64 FileOffsetToData; + llvm::yaml::Hex64 FileOffsetToRelocations; + llvm::yaml::Hex64 FileOffsetToLineNumbers; + llvm::yaml::Hex16 NumberOfRelocations; + llvm::yaml::Hex16 NumberOfLineNumbers; + XCOFF::SectionTypeFlags Flags; + yaml::BinaryRef SectionData; + std::vector Relocations; +};; + struct Symbol { StringRef SymbolName; - llvm::yaml::Hex32 Value; // Symbol value; storage class-dependent. + llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent. StringRef SectionName; llvm::yaml::Hex16 Type; XCOFF::StorageClass StorageClass; - uint8_t NumberOfAuxEntries; // Number of auxiliary entries + llvm::yaml::Hex8 NumberOfAuxEntries; }; struct Object { FileHeader Header; + std::vector
Sections; std::vector Symbols; Object(); }; } // namespace XCOFFYAML } // namespace llvm + LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol) +LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation) +LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section) + namespace llvm { namespace yaml { +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, XCOFF::SectionTypeFlags &Value); +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, XCOFF::StorageClass &Value); }; @@ -61,6 +91,14 @@ static void mapping(IO &IO, XCOFFYAML::Object &Obj); }; +template <> struct MappingTraits { + static void mapping(IO &IO, XCOFFYAML::Relocation &R); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, XCOFFYAML::Section &S); +}; + template <> struct MappingTraits { static void mapping(IO &IO, XCOFFYAML::Symbol &S); }; diff --git a/llvm/include/llvm/ObjectYAML/yaml2obj.h b/llvm/include/llvm/ObjectYAML/yaml2obj.h --- a/llvm/include/llvm/ObjectYAML/yaml2obj.h +++ b/llvm/include/llvm/ObjectYAML/yaml2obj.h @@ -40,6 +40,10 @@ struct Object; } +namespace XCOFFYAML { +struct Object; +} + namespace ArchYAML { struct Archive; } @@ -58,6 +62,7 @@ bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); +bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler, unsigned DocNum = 1, uint64_t MaxSize = UINT64_MAX); diff --git a/llvm/lib/ObjectYAML/CMakeLists.txt b/llvm/lib/ObjectYAML/CMakeLists.txt --- a/llvm/lib/ObjectYAML/CMakeLists.txt +++ b/llvm/lib/ObjectYAML/CMakeLists.txt @@ -18,6 +18,7 @@ MinidumpYAML.cpp WasmEmitter.cpp WasmYAML.cpp + XCOFFEmitter.cpp XCOFFYAML.cpp YAML.cpp yaml2obj.cpp diff --git a/llvm/lib/ObjectYAML/ObjectYAML.cpp b/llvm/lib/ObjectYAML/ObjectYAML.cpp --- a/llvm/lib/ObjectYAML/ObjectYAML.cpp +++ b/llvm/lib/ObjectYAML/ObjectYAML.cpp @@ -59,6 +59,9 @@ } else if (IO.mapTag("!WASM")) { ObjectFile.Wasm.reset(new WasmYAML::Object()); MappingTraits::mapping(IO, *ObjectFile.Wasm); + } else if (IO.mapTag("!XCOFF")) { + ObjectFile.Xcoff.reset(new XCOFFYAML::Object()); + MappingTraits::mapping(IO, *ObjectFile.Xcoff); } else if (const Node *N = In.getCurrentNode()) { if (N->getRawTag().empty()) IO.setError("YAML Object File missing document type tag!"); diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp --- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp +++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp @@ -0,0 +1,325 @@ +//===- yaml2xcoff - Convert YAML to a xcoff object file -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// The xcoff component of yaml2obj. +/// +//===----------------------------------------------------------------------===// +#include "llvm/ADT/StringSwitch.h" +#include "llvm/BinaryFormat/XCOFF.h" +#include "llvm/Object/XCOFFObjectFile.h" +#include "llvm/ObjectYAML/ObjectYAML.h" +#include "llvm/ObjectYAML/yaml2obj.h" +#include "llvm/Support/EndianStream.h" +#include "llvm/Support/raw_ostream.h" + +// Only 32-bit supported now. + +using namespace llvm; + +namespace { + +constexpr unsigned DefaultSectionAlign = 4; +constexpr int16_t MaxSectionIndex = INT16_MAX; +constexpr uint32_t MaxRawDataSize = UINT32_MAX; + +class XCOFFWriter { +public: + XCOFFWriter(XCOFFYAML::Object &Obj, raw_ostream &OS, yaml::ErrorHandler EH) + : Obj(Obj), W(OS, support::big), ErrHandler(EH) {} + bool writeXCOFF(); + +private: + bool assignAddressesAndIndices(); + void writeFileHeader(); + void writeSectionHeader(); + bool writeSectionData(); + bool writeRelocations(); + bool writeSymbols(); + + XCOFFYAML::Object &Obj; + support::endian::Writer W; + yaml::ErrorHandler ErrHandler; + uint64_t StartOffset; + // Maps the section name to its corrresponding section index. + DenseMap SectionIndexMap; + // Initializes the value of number/offset/address by inferring from the + // contents of the YAML. + XCOFFYAML::FileHeader InitFileHdr; + std::vector InitSections; +}; + +bool XCOFFWriter::assignAddressesAndIndices() { + // Overwrites some fields of InitSections and InitFileHdr with inferred values + // from the contents of the YAML. + InitSections = Obj.Sections; + InitFileHdr = Obj.Header; + // XCOFF has special section numbers for symbols: + // -2 Specifies N_DEBUG, a special symbolic debugging symbol. + // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not + // relocatable. + // 0 Specifies N_UNDEF, an undefined external symbol. + SectionIndexMap[StringRef("N_DEBUG")] = XCOFF::N_DEBUG; + SectionIndexMap[StringRef("N_ABS")] = XCOFF::N_ABS; + SectionIndexMap[StringRef("N_UNDEF")] = XCOFF::N_UNDEF; + + uint64_t CurrentOffset = + sizeof(XCOFF::FileHeader32) /* TODO: + auxiliaryHeaderSize() */ + + InitSections.size() * sizeof(XCOFF::SectionHeader32); + uint64_t CurrentSecAddr = 0; + for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) { + if (CurrentOffset > MaxRawDataSize) { + ErrHandler("section data overflowed the MaxRawDataSize: " + + Twine(MaxRawDataSize)); + return false; + } + // Assigns indices for sections. + if (!SectionIndexMap[InitSections[I].SectionName]) { + // The section index starts from 1. + SectionIndexMap[InitSections[I].SectionName] = I + 1; + if ((I + 1) > MaxSectionIndex) { + ErrHandler("section index overflowed the MaxSectionIndex: " + + Twine(MaxSectionIndex)); + return false; + } + } + // Calculates the FileOffsetToData and data size for sections. + if (InitSections[I].SectionData.binary_size()) { + InitSections[I].FileOffsetToData = CurrentOffset; + CurrentOffset += InitSections[I].SectionData.binary_size(); + // Make sure the address of the next section aligned to + // DefaultSectionAlign. + CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign); + InitSections[I].Size = CurrentOffset - InitSections[I].FileOffsetToData; + CurrentSecAddr += InitSections[I].Size; + } + // Calculate the physical/virtual address. + // This field should contain 0 for all sections except the .text , .data , + // and .bss sections. + if (InitSections[I].Flags != XCOFF::STYP_TEXT && + InitSections[I].Flags != XCOFF::STYP_DATA && + InitSections[I].Flags != XCOFF::STYP_BSS) + InitSections[I].Address = 0; + else + InitSections[I].Address = CurrentSecAddr; + } + // Calculates FileOffsetToRelocations for sections. + for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) { + if (!InitSections[I].Relocations.empty()) { + InitSections[I].NumberOfRelocations = InitSections[I].Relocations.size(); + InitSections[I].FileOffsetToRelocations = CurrentOffset; + CurrentOffset += InitSections[I].NumberOfRelocations * + XCOFF::RelocationSerializationSize32; + if (CurrentOffset > MaxRawDataSize) { + ErrHandler("relocation data overflowed the MaxRawDataSize: " + + Twine(MaxRawDataSize)); + return false; + } + } + } + // TODO: Calculate FileOffsetToLineNumbers when line number supported. + // Calculates file header related info. + InitFileHdr.NumberOfSections = Obj.Sections.size(); + InitFileHdr.NumberOfSymTableEntries = Obj.Symbols.size(); + for (XCOFFYAML::Symbol YamlSym : Obj.Symbols) + InitFileHdr.NumberOfSymTableEntries += YamlSym.NumberOfAuxEntries; + // Calculates SymbolTableOffset for file header. + if (InitFileHdr.NumberOfSymTableEntries) { + InitFileHdr.SymbolTableOffset = CurrentOffset; + CurrentOffset += + InitFileHdr.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize; + if (CurrentOffset > MaxRawDataSize) { + ErrHandler("symbol address overflowed the MaxRawDataSize: " + + Twine(MaxRawDataSize)); + return false; + } + } + return true; +} + +void XCOFFWriter::writeFileHeader() { + // Target machine. The default format of object file is XCOFF32. + W.write(Obj.Header.Magic ? (uint16_t)Obj.Header.Magic : 0x01DF); + // Number of sections. + W.write(Obj.Header.NumberOfSections ? Obj.Header.NumberOfSections + : InitFileHdr.NumberOfSections); + // Time and date of file creation. + W.write(Obj.Header.TimeStamp); + // Byte offset to symbol table start. + W.write(Obj.Header.SymbolTableOffset + ? Obj.Header.SymbolTableOffset + : InitFileHdr.SymbolTableOffset); + // Number of entries in symbol table. + W.write(Obj.Header.NumberOfSymTableEntries + ? Obj.Header.NumberOfSymTableEntries + : InitFileHdr.NumberOfSymTableEntries); + // Number of bytes in optional header. Not supported yet. + W.write(Obj.Header.AuxHeaderSize); + // Flags. + W.write(Obj.Header.Flags); +} + +void XCOFFWriter::writeSectionHeader() { + for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) { + XCOFFYAML::Section YamlSec = Obj.Sections[I]; + XCOFFYAML::Section DerivedSec = InitSections[I]; + // Section name. + W.OS.write(YamlSec.SectionName.data(), sizeof(XCOFF::NameSize)); + // Physical Address. + W.write(YamlSec.Address ? YamlSec.Address : DerivedSec.Address); + // Virtual address (same as physical address). + W.write(YamlSec.Address ? YamlSec.Address : DerivedSec.Address); + // Section size. + W.write(YamlSec.Size ? YamlSec.Size : DerivedSec.Size); + // Offset in file to raw data for section. + W.write(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData + : DerivedSec.FileOffsetToData); + // Offset in file to relocation entries for section. + W.write(YamlSec.FileOffsetToRelocations + ? YamlSec.FileOffsetToRelocations + : DerivedSec.FileOffsetToRelocations); + // Offset in file to line number entries for section. + W.write(YamlSec.FileOffsetToLineNumbers); + // Number of relocation entries. + W.write(YamlSec.NumberOfRelocations + ? YamlSec.NumberOfRelocations + : DerivedSec.NumberOfRelocations); + // Number of line number entries. + W.write(YamlSec.NumberOfLineNumbers); + // Flags to define the section type. + W.write(YamlSec.Flags); + } +} + +bool XCOFFWriter::writeSectionData() { + for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) { + XCOFFYAML::Section YamlSec = Obj.Sections[I]; + if (YamlSec.SectionData.binary_size()) { + // Fill the padding size with zeros. + int32_t PaddingSize = + InitSections[I].FileOffsetToData - (W.OS.tell() - StartOffset); + if (PaddingSize < 0) { + ErrHandler("redundant data was wrote before section data"); + return false; + } + W.OS.write_zeros(PaddingSize); + YamlSec.SectionData.writeAsBinary(W.OS); + } + } + return true; +} + +bool XCOFFWriter::writeRelocations() { + for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) { + XCOFFYAML::Section YamlSec = Obj.Sections[I]; + if (!YamlSec.Relocations.empty()) { + int32_t PaddingSize = + InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset); + if (PaddingSize < 0) { + ErrHandler("redundant data was wrote before relocations"); + return false; + } + W.OS.write_zeros(PaddingSize); + for (XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations) { + W.write(YamlRel.VirtualAddress); + W.write(YamlRel.SymbolIndex); + W.write(YamlRel.Info); + W.write(YamlRel.Type); + } + } + } + return true; +} + +bool XCOFFWriter::writeSymbols() { + int32_t PaddingSize = + (uint64_t)InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset); + if (PaddingSize < 0) { + ErrHandler("redundant data was wrote before symbols"); + return false; + } + W.OS.write_zeros(PaddingSize); + for (XCOFFYAML::Symbol &YamlSym : Obj.Symbols) { + // Symbol name. + if (YamlSym.SymbolName.size() > XCOFF::NameSize) { + ErrHandler("string table is not supported yet"); + return false; + } + W.OS.write(YamlSym.SymbolName.data(), sizeof(XCOFF::NameSize)); + // Symbol value; storage class-dependent. + W.write(YamlSym.Value); + // Section number of symbol. + W.write(SectionIndexMap[YamlSym.SectionName]); + // Basic and derived type specification. + W.write(YamlSym.Type); + // Storage class of symbol. + W.write(YamlSym.StorageClass); + // Number of auxiliary entries. + W.write(YamlSym.NumberOfAuxEntries); + for (uint8_t I = 0, E = YamlSym.NumberOfAuxEntries; I < E; ++I) { + // Now output the auxiliary entry. + // TODO: Auxiliary entry is not supported yet. + // The auxiliary entries for a symbol follow its symbol table entry. The + // length of each auxiliary entry is the same as a symbol table entry (18 + // bytes). The format and quantity of auxiliary entries depend on the + // storage class (n_sclass) and type (n_type) of the symbol table entry. + W.write(0); + W.write(0); + W.write(0); + // Symbol type. + W.write(0); + // Storage mapping class. + W.write(0); + // Reserved (x_stab). + W.write(0); + // Reserved (x_snstab). + W.write(0); + } + } + return true; +} + +bool XCOFFWriter::writeXCOFF() { + // TODO: Add support for 64-bit. + if ((uint16_t)Obj.Header.Magic != 0x01DF) { + ErrHandler("only XCOFF32 is supported now"); + return false; + } + bool Res = true; + Res &= assignAddressesAndIndices(); + StartOffset = W.OS.tell(); + // Write Filer Header. + writeFileHeader(); + // TODO: Add support for the auxiliary header. + if (!Obj.Sections.empty()) { + // Write Section Header. + writeSectionHeader(); + // Write Section Data if any. + Res &= writeSectionData(); + // Write relocations if any. + Res &= writeRelocations(); + } + if (!Obj.Symbols.empty()) + // Write symbol table. + Res &= writeSymbols(); + // TODO: Add support for the string table. + return Res; +} + +} // end anonymous namespace + +namespace llvm { +namespace yaml { + +bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { + XCOFFWriter Writer(Doc, Out, EH); + return Writer.writeXCOFF(); +} + +} // namespace yaml +} // namespace llvm diff --git a/llvm/lib/ObjectYAML/XCOFFYAML.cpp b/llvm/lib/ObjectYAML/XCOFFYAML.cpp --- a/llvm/lib/ObjectYAML/XCOFFYAML.cpp +++ b/llvm/lib/ObjectYAML/XCOFFYAML.cpp @@ -23,6 +23,25 @@ namespace yaml { +void ScalarEnumerationTraits::enumeration( + IO &IO, XCOFF::SectionTypeFlags &Value) { +#define ECase(X) IO.enumCase(Value, #X, XCOFF::X) + ECase(STYP_PAD); + ECase(STYP_DWARF); + ECase(STYP_TEXT); + ECase(STYP_DATA); + ECase(STYP_BSS); + ECase(STYP_EXCEPT); + ECase(STYP_INFO); + ECase(STYP_TDATA); + ECase(STYP_TBSS); + ECase(STYP_LOADER); + ECase(STYP_DEBUG); + ECase(STYP_TYPCHK); + ECase(STYP_OVRFLO); +#undef ECase +} + void ScalarEnumerationTraits::enumeration( IO &IO, XCOFF::StorageClass &Value) { #define ECase(X) IO.enumCase(Value, #X, XCOFF::X) @@ -81,28 +100,50 @@ void MappingTraits::mapping( IO &IO, XCOFFYAML::FileHeader &FileHdr) { - IO.mapRequired("MagicNumber", FileHdr.Magic); - IO.mapRequired("NumberOfSections", FileHdr.NumberOfSections); - IO.mapRequired("CreationTime", FileHdr.TimeStamp); - IO.mapRequired("OffsetToSymbolTable", FileHdr.SymbolTableOffset); - IO.mapRequired("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries); - IO.mapRequired("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize); - IO.mapRequired("Flags", FileHdr.Flags); + IO.mapOptional("MagicNumber", FileHdr.Magic); + IO.mapOptional("NumberOfSections", FileHdr.NumberOfSections); + IO.mapOptional("CreationTime", FileHdr.TimeStamp); + IO.mapOptional("OffsetToSymbolTable", FileHdr.SymbolTableOffset); + IO.mapOptional("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries); + IO.mapOptional("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize); + IO.mapOptional("Flags", FileHdr.Flags); +} + +void MappingTraits::mapping(IO &IO, XCOFFYAML::Relocation &R) { + IO.mapRequired("Address", R.VirtualAddress); + IO.mapRequired("Symbol", R.SymbolIndex); + IO.mapOptional("Info", R.Info); + IO.mapOptional("Type", R.Type); +} + +void MappingTraits::mapping(IO &IO, XCOFFYAML::Section &Sec) { + IO.mapRequired("Name", Sec.SectionName); + IO.mapOptional("Address", Sec.Address); + IO.mapOptional("Size", Sec.Size); + IO.mapOptional("FileOffsetToData", Sec.FileOffsetToData); + IO.mapOptional("FileOffsetToRelocations", Sec.FileOffsetToRelocations); + IO.mapOptional("FileOffsetToLineNumbers", Sec.FileOffsetToLineNumbers); + IO.mapOptional("NumberOfRelocations", Sec.NumberOfRelocations); + IO.mapOptional("NumberOfLineNumbers", Sec.NumberOfLineNumbers); + IO.mapOptional("Flags", Sec.Flags); + IO.mapOptional("SectionData", Sec.SectionData); + IO.mapOptional("Relocations", Sec.Relocations); } void MappingTraits::mapping(IO &IO, XCOFFYAML::Symbol &S) { IO.mapRequired("Name", S.SymbolName); - IO.mapRequired("Value", S.Value); + IO.mapOptional("Value", S.Value); IO.mapRequired("Section", S.SectionName); - IO.mapRequired("Type", S.Type); - IO.mapRequired("StorageClass", S.StorageClass); - IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries); + IO.mapOptional("Type", S.Type); + IO.mapOptional("StorageClass", S.StorageClass); + IO.mapOptional("NumberOfAuxEntries", S.NumberOfAuxEntries); } void MappingTraits::mapping(IO &IO, XCOFFYAML::Object &Obj) { IO.mapTag("!XCOFF", true); IO.mapRequired("FileHeader", Obj.Header); - IO.mapRequired("Symbols", Obj.Symbols); + IO.mapOptional("Sections", Obj.Sections); + IO.mapOptional("Symbols", Obj.Symbols); } } // namespace yaml diff --git a/llvm/lib/ObjectYAML/yaml2obj.cpp b/llvm/lib/ObjectYAML/yaml2obj.cpp --- a/llvm/lib/ObjectYAML/yaml2obj.cpp +++ b/llvm/lib/ObjectYAML/yaml2obj.cpp @@ -44,6 +44,8 @@ return yaml2minidump(*Doc.Minidump, Out, ErrHandler); if (Doc.Wasm) return yaml2wasm(*Doc.Wasm, Out, ErrHandler); + if (Doc.Xcoff) + return yaml2xcoff(*Doc.Xcoff, Out, ErrHandler); ErrHandler("unknown document type"); return false; diff --git a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml --- a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml +++ b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml @@ -16,65 +16,65 @@ # CHECK-NEXT: Section: N_DEBUG # CHECK-NEXT: Type: 0x3 # CHECK-NEXT: StorageClass: C_FILE -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: i # CHECK-NEXT: Value: 0x0 # CHECK-NEXT: Section: N_UNDEF # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_EXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: TestforXcoff # CHECK-NEXT: Value: 0x0 # CHECK-NEXT: Section: N_UNDEF # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_EXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: .text # CHECK-NEXT: Value: 0x0 # CHECK-NEXT: Section: .text # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: .main # CHECK-NEXT: Value: 0x0 # CHECK-NEXT: Section: .text # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_EXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: main # CHECK-NEXT: Value: 0x60 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: main # CHECK-NEXT: Value: 0x60 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_EXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: .data # CHECK-NEXT: Value: 0x70 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: TOC # CHECK-NEXT: Value: 0x74 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: i # CHECK-NEXT: Value: 0x74 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: - Name: TestforXcoff # CHECK-NEXT: Value: 0x78 # CHECK-NEXT: Section: .data # CHECK-NEXT: Type: 0x0 # CHECK-NEXT: StorageClass: C_HIDEXT -# CHECK-NEXT: NumberOfAuxEntries: 1 +# CHECK-NEXT: NumberOfAuxEntries: 0x1 # CHECK-NEXT: ... diff --git a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml --- a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml +++ b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml @@ -0,0 +1,134 @@ +# Check that yaml2obj automatically assigns ommited fields with values. +# RUN: yaml2obj %s -o %t +# RUN: llvm-readobj --headers %t | FileCheck %s --check-prefix=CHECK-HEADERS +# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=CHECK-SYMBOLS + +--- !XCOFF +FileHeader: + MagicNumber: 0x1DF +Sections: + - Name: .text + Flags: STYP_TEXT + - Name: .data + SectionData: "1001" + Flags: STYP_DATA + Relocations: + - Address: 0x3A + Symbol: 1 + Info: 0x04 + Type: 0x02 +Symbols: + - Name: .file + Value: 0x0 + Section: N_DEBUG + Type: 0x0 + StorageClass: C_FILE + NumberOfAuxEntries: 1 + - Name: .text + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + - Name: i + Value: 0x0 + Section: .data + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + +# CHECK-HEADERS: FileHeader { +# CHECK-HEADERS-NEXT: Magic: 0x1DF +# CHECK-HEADERS-NEXT: NumberOfSections: 2 +# CHECK-HEADERS-NEXT: TimeStamp: None (0x0) +# CHECK-HEADERS-NEXT: SymbolTableOffset: 0x72 +# CHECK-HEADERS-NEXT: SymbolTableEntries: 6 +# CHECK-HEADERS-NEXT: OptionalHeaderSize: 0x0 +# CHECK-HEADERS-NEXT: Flags: 0x0 +# CHECK-HEADERS-NEXT: } + +# CHECK-HEADERS: Sections [ +# CHECK-HEADERS-NEXT: Section { +# CHECK-HEADERS-NEXT: Index: 1 +# CHECK-HEADERS-NEXT: Name: .text +# CHECK-HEADERS: PhysicalAddress: 0x0 +# CHECK-HEADERS-NEXT: VirtualAddress: 0x0 +# CHECK-HEADERS-NEXT: Size: 0x0 +# CHECK-HEADERS-NEXT: RawDataOffset: 0x0 +# CHECK-HEADERS-NEXT: RelocationPointer: 0x0 +# CHECK-HEADERS-NEXT: LineNumberPointer: 0x0 +# CHECK-HEADERS-NEXT: NumberOfRelocations: 0 +# CHECK-HEADERS-NEXT: NumberOfLineNumbers: 0 +# CHECK-HEADERS-NEXT: Type: STYP_TEXT (0x20) +# CHECK-HEADERS-NEXT: } +# CHECK-HEADERS-NEXT: Section { +# CHECK-HEADERS-NEXT: Index: 2 +# CHECK-HEADERS-NEXT: Name: .data +# CHECK-HEADERS: PhysicalAddress: 0x4 +# CHECK-HEADERS-NEXT: VirtualAddress: 0x4 +# CHECK-HEADERS-NEXT: Size: 0x4 +# CHECK-HEADERS-NEXT: RawDataOffset: 0x64 +# CHECK-HEADERS-NEXT: RelocationPointer: 0x68 +# CHECK-HEADERS-NEXT: LineNumberPointer: 0x0 +# CHECK-HEADERS-NEXT: NumberOfRelocations: 1 +# CHECK-HEADERS-NEXT: NumberOfLineNumbers: 0 +# CHECK-HEADERS-NEXT: Type: STYP_DATA (0x40) +# CHECK-HEADERS-NEXT: } +# CHECK-HEADERS-NEXT: ] + +# CHECK-SYMBOLS: Symbols [ +# CHECK-SYMBOLS-NEXT: Symbol { +# CHECK-SYMBOLS-NEXT: Index: 0 +# CHECK-SYMBOLS-NEXT: Name: .file +# CHECK-SYMBOLS: Value (SymbolTableIndex): 0x0 +# CHECK-SYMBOLS-NEXT: Section: N_DEBUG +# CHECK-SYMBOLS-NEXT: Source Language ID: TB_C (0x0) +# CHECK-SYMBOLS: StorageClass: C_FILE (0x67) +# CHECK-SYMBOLS-NEXT: NumberOfAuxEntries: 1 +# CHECK-SYMBOLS-NEXT: File Auxiliary Entry { +# CHECK-SYMBOLS-NEXT: Index: 1 +# CHECK-SYMBOLS-NEXT: Name: +# CHECK-SYMBOLS-NEXT: Type: XFT_FN (0x0) +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: Symbol { +# CHECK-SYMBOLS-NEXT: Index: 2 +# CHECK-SYMBOLS-NEXT: Name: .text +# CHECK-SYMBOLS: Value (RelocatableAddress): 0x0 +# CHECK-SYMBOLS-NEXT: Section: .text +# CHECK-SYMBOLS: Type: 0x0 +# CHECK-SYMBOLS-NEXT: StorageClass: C_HIDEXT (0x6B) +# CHECK-SYMBOLS-NEXT: NumberOfAuxEntries: 1 +# CHECK-SYMBOLS-NEXT: CSECT Auxiliary Entry { +# CHECK-SYMBOLS-NEXT: Index: 3 +# CHECK-SYMBOLS-NEXT: SectionLen: 0 +# CHECK-SYMBOLS-NEXT: ParameterHashIndex: 0x0 +# CHECK-SYMBOLS-NEXT: TypeChkSectNum: 0x0 +# CHECK-SYMBOLS-NEXT: SymbolAlignmentLog2: 0 +# CHECK-SYMBOLS-NEXT: SymbolType: XTY_ER (0x0) +# CHECK-SYMBOLS-NEXT: StorageMappingClass: XMC_PR (0x0) +# CHECK-SYMBOLS-NEXT: StabInfoIndex: 0x0 +# CHECK-SYMBOLS-NEXT: StabSectNum: 0x0 +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: Symbol { +# CHECK-SYMBOLS-NEXT: Index: 4 +# CHECK-SYMBOLS-NEXT: Name: i +# CHECK-SYMBOLS: Value (RelocatableAddress): 0x0 +# CHECK-SYMBOLS-NEXT: Section: .data +# CHECK-SYMBOLS: Type: 0x0 +# CHECK-SYMBOLS-NEXT: StorageClass: C_EXT (0x2) +# CHECK-SYMBOLS-NEXT: NumberOfAuxEntries: 1 +# CHECK-SYMBOLS-NEXT: CSECT Auxiliary Entry { +# CHECK-SYMBOLS-NEXT: Index: 5 +# CHECK-SYMBOLS-NEXT: SectionLen: 0 +# CHECK-SYMBOLS-NEXT: ParameterHashIndex: 0x0 +# CHECK-SYMBOLS-NEXT: TypeChkSectNum: 0x0 +# CHECK-SYMBOLS-NEXT: SymbolAlignmentLog2: 0 +# CHECK-SYMBOLS-NEXT: SymbolType: XTY_ER (0x0) +# CHECK-SYMBOLS-NEXT: StorageMappingClass: XMC_PR (0x0) +# CHECK-SYMBOLS-NEXT: StabInfoIndex: 0x0 +# CHECK-SYMBOLS-NEXT: StabSectNum: 0x0 +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: } +# CHECK-SYMBOLS-NEXT: ] diff --git a/llvm/test/tools/yaml2obj/XCOFF/mini-doc.yaml b/llvm/test/tools/yaml2obj/XCOFF/mini-doc.yaml deleted file mode 100644 diff --git a/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn @@ -26,6 +26,7 @@ "ObjectYAML.cpp", "WasmEmitter.cpp", "WasmYAML.cpp", + "XCOFFEmitter.cpp" "XCOFFYAML.cpp", "YAML.cpp", "yaml2obj.cpp",