diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h index 443bcfc9479a8..be6850216dbe2 100644 --- a/llvm/include/llvm/BinaryFormat/GOFF.h +++ b/llvm/include/llvm/BinaryFormat/GOFF.h @@ -157,6 +157,12 @@ enum ESDAlignment : uint8_t { ESD_ALIGN_4Kpage = 12, }; +enum TXTRecordStyle : uint8_t { + TXT_RS_Byte = 0, + TXT_RS_Structured = 1, + TXT_RS_Unstructured = 2, +}; + enum ENDEntryPointRequest : uint8_t { END_EPR_None = 0, END_EPR_EsdidOffset = 1, diff --git a/llvm/include/llvm/ObjectYAML/GOFFYAML.h b/llvm/include/llvm/ObjectYAML/GOFFYAML.h index f9bf45e95bd3a..cc88def3aea4a 100644 --- a/llvm/include/llvm/ObjectYAML/GOFFYAML.h +++ b/llvm/include/llvm/ObjectYAML/GOFFYAML.h @@ -20,11 +20,104 @@ #include namespace llvm { +namespace GOFF { + +enum ESDFlags { + ESD_FillByteValuePresent = 1 << 7, + ESD_SymbolDisplayFlag = 1 << 6, + ESD_SymbolRenamingFlag = 1 << 5, + ESD_RemovableClass = 1 << 4 +}; + +enum { + ESD_Mask_ERST = 0x07, + ESD_Mask_RQW = 0x07, + ESD_Mask_TextStyle = 0xf0, + ESD_Mask_BindingAlgorithm = 0x0f, +}; + +enum ESDBAFlags { + ESD_BA_Movable = 0x01, + ESD_BA_ReadOnly = 0x2, + ESD_BA_NoPrime = 0x4, + ESD_BA_COMMON = 0x8, + ESD_BA_Indirect = 0x10, +}; + +} // end namespace GOFF // The structure of the yaml files is not an exact 1:1 match to GOFF. In order // to use yaml::IO, we use these structures which are closer to the source. namespace GOFFYAML { +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDSYMBOLTYPE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDNAMESPACEID) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDFlags) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDAMODE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDRMODE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDTEXTSTYLE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDBINDINGALGORITHM) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDTASKINGBEHAVIOR) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDEXECUTABLE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDLINKAGETYPE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDBINDINGSTRENGTH) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDLOADINGBEHAVIOR) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDBINDINGSCOPE) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ESDALIGNMENT) +LLVM_YAML_STRONG_TYPEDEF(uint64_t, GOFF_BAFLAGS) + +LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_TEXTRECORDSTYLE) + +struct RecordBase { + enum RecordBaseKind { RBK_Symbol }; + +private: + const RecordBaseKind Kind; + +protected: + RecordBase(RecordBaseKind Kind) : Kind(Kind) {} + +public: + RecordBaseKind getKind() const { return Kind; } +}; + +using RecordPtr = std::unique_ptr; + +struct Symbol : public RecordBase { + Symbol() : RecordBase(RBK_Symbol) {} + + StringRef Name; + GOFF_ESDSYMBOLTYPE Type; + uint32_t ID; + uint32_t OwnerID; + uint32_t Address; + uint32_t Length; + uint32_t ExtAttrID; + uint32_t ExtAttrOffset; + GOFF_ESDNAMESPACEID NameSpace; + GOFF_ESDFlags Flags; + uint8_t FillByteValue; + uint32_t PSectID; + uint32_t Priority; + llvm::yaml::Hex64 Signature; + GOFF_ESDAMODE Amode; + GOFF_ESDRMODE Rmode; + GOFF_ESDTEXTSTYLE TextStyle; + GOFF_ESDBINDINGALGORITHM BindingAlgorithm; + GOFF_ESDTASKINGBEHAVIOR TaskingBehavior; + GOFF_ESDEXECUTABLE Executable; + GOFF_ESDLINKAGETYPE LinkageType; + GOFF_ESDBINDINGSTRENGTH BindingStrength; + GOFF_ESDLOADINGBEHAVIOR LoadingBehavior; + GOFF_ESDBINDINGSCOPE BindingScope; + GOFF_ESDALIGNMENT Alignment; + GOFF_BAFLAGS BAFlags; + + static bool classof(const RecordBase *Rec) { + return Rec->getKind() == RBK_Symbol; + } +}; + struct FileHeader { uint32_t TargetEnvironment = 0; uint32_t TargetOperatingSystem = 0; @@ -38,12 +131,45 @@ struct FileHeader { struct Object { FileHeader Header; + std::vector Records; Object(); }; + } // end namespace GOFFYAML } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(GOFFYAML::RecordPtr) + +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDSYMBOLTYPE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDNAMESPACEID) +LLVM_YAML_DECLARE_BITSET_TRAITS(GOFFYAML::GOFF_ESDFlags) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDAMODE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDRMODE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDTEXTSTYLE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDBINDINGALGORITHM) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDTASKINGBEHAVIOR) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDEXECUTABLE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDLINKAGETYPE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDBINDINGSTRENGTH) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDLOADINGBEHAVIOR) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDBINDINGSCOPE) +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ESDALIGNMENT) +LLVM_YAML_DECLARE_BITSET_TRAITS(GOFFYAML::GOFF_BAFLAGS) + +LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_TEXTRECORDSTYLE) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Symbol) LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::FileHeader) LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Object) +namespace llvm { +namespace yaml { + +template <> struct CustomMappingTraits { + static void inputOne(IO &IO, StringRef Key, GOFFYAML::RecordPtr &Elem); + static void output(IO &IO, GOFFYAML::RecordPtr &Elem); +}; + +} // end namespace yaml +} // end namespace llvm #endif // LLVM_OBJECTYAML_GOFFYAML_H diff --git a/llvm/lib/ObjectYAML/GOFFEmitter.cpp b/llvm/lib/ObjectYAML/GOFFEmitter.cpp index 345904407e1d2..c0dff5b8fcc75 100644 --- a/llvm/lib/ObjectYAML/GOFFEmitter.cpp +++ b/llvm/lib/ObjectYAML/GOFFEmitter.cpp @@ -175,6 +175,7 @@ class GOFFOstream : public raw_ostream { class GOFFState { void writeHeader(GOFFYAML::FileHeader &FileHdr); void writeEnd(); + void writeSymbol(GOFFYAML::Symbol Sym); void reportError(const Twine &Msg) { ErrHandler(Msg); @@ -245,6 +246,53 @@ void GOFFState::writeHeader(GOFFYAML::FileHeader &FileHdr) { } } +void GOFFState::writeSymbol(GOFFYAML::Symbol Sym) { + SmallString<80> SymName; + if (std::error_code EC = ConverterEBCDIC::convertToEBCDIC(Sym.Name, SymName)) + reportError("cannot convert '" + Sym.Name + "' to EBCDIC: " + EC.message()); + size_t SymNameLength = SymName.size(); + if (SymNameLength > GOFF::MaxDataLength) + reportError("symbol name is too long: " + Twine(SymNameLength) + + ". Max length is: " + Twine(GOFF::MaxDataLength)); + + const unsigned NameLengthOffset = 69; + GW.makeNewRecord(GOFF::RT_ESD, NameLengthOffset + SymNameLength); + GW << binaryBe(Sym.Type) // Symbol type + << binaryBe(Sym.ID) // ESDID + << binaryBe(Sym.OwnerID) // Owner ESDID + << binaryBe(uint32_t(0)) // Reserved + << binaryBe(Sym.Address) // Offset/Address + << binaryBe(uint32_t(0)) // Reserved + << binaryBe(Sym.Length) // Length + << binaryBe(Sym.ExtAttrID) // Extended attributes + << binaryBe(Sym.ExtAttrOffset) // Extended attributes data offset + << binaryBe(uint32_t(0)) // Reserved + << binaryBe(Sym.NameSpace) // Namespace ID + << binaryBe(Sym.Flags) // Flags + << binaryBe(Sym.FillByteValue) // Fill byte value + << binaryBe(uint8_t(0)) // Reserved + << binaryBe(Sym.PSectID) // PSECT ID + << binaryBe(Sym.Priority); // Priority + if (Sym.Signature) + GW << Sym.Signature; // Signature + else + GW << zeros(8); +#define BIT(E, N) (Sym.BAFlags & GOFF::E ? 1 << (7 - N) : 0) + GW << binaryBe(Sym.Amode) // Behavioral attributes - Amode + << binaryBe(Sym.Rmode) // Behavioral attributes - Rmode + << binaryBe(uint8_t(Sym.TextStyle << 4 | Sym.BindingAlgorithm)) + << binaryBe(uint8_t(Sym.TaskingBehavior << 5 | BIT(ESD_BA_Movable, 3) | + BIT(ESD_BA_ReadOnly, 4) | Sym.Executable)) + << binaryBe(uint8_t(BIT(ESD_BA_NoPrime, 1) | Sym.BindingStrength)) + << binaryBe(uint8_t(Sym.LoadingBehavior << 6 | BIT(ESD_BA_COMMON, 2) | + BIT(ESD_BA_Indirect, 3) | Sym.BindingScope)) + << binaryBe(uint8_t(Sym.LinkageType << 5 | Sym.Alignment)) + << zeros(3) // Behavioral attributes - Reserved + << binaryBe(static_cast(SymNameLength)) // Name length + << SymName.str(); +#undef BIT +} + void GOFFState::writeEnd() { GW.makeNewRecord(GOFF::RT_END, GOFF::PayloadLength); GW << binaryBe(uint8_t(0)) // No entry point @@ -259,6 +307,13 @@ bool GOFFState::writeObject() { writeHeader(Doc.Header); if (HasError) return false; + // Iterate over all records. + for (const auto &[RecordNum, Rec] : llvm::enumerate(Doc.Records)) { + if (const auto *Sym = dyn_cast(Rec.get())) + writeSymbol(*Sym); + else + reportError("unknown record type on record index" + Twine(RecordNum)); + } writeEnd(); return true; } diff --git a/llvm/lib/ObjectYAML/GOFFYAML.cpp b/llvm/lib/ObjectYAML/GOFFYAML.cpp index ae857980a521b..5aae998799dbe 100644 --- a/llvm/lib/ObjectYAML/GOFFYAML.cpp +++ b/llvm/lib/ObjectYAML/GOFFYAML.cpp @@ -23,6 +23,191 @@ Object::Object() {} namespace yaml { +#define ECase(X) IO.enumCase(Value, #X, GOFF::X) +#define BCase(X) IO.bitSetCase(Value, #X, GOFF::X) +#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, GOFF::X, GOFF::M) +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDSYMBOLTYPE &Value) { + ECase(ESD_ST_SectionDefinition); + ECase(ESD_ST_ElementDefinition); + ECase(ESD_ST_LabelDefinition); + ECase(ESD_ST_PartReference); + ECase(ESD_ST_ExternalReference); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDNAMESPACEID &Value) { + ECase(ESD_NS_ProgramManagementBinder); + ECase(ESD_NS_NormalName); + ECase(ESD_NS_PseudoRegister); + ECase(ESD_NS_Parts); + IO.enumFallback(Value); +} + +void ScalarBitSetTraits::bitset( + IO &IO, GOFFYAML::GOFF_ESDFlags &Value) { + BCase(ESD_FillByteValuePresent); + BCase(ESD_SymbolDisplayFlag); + BCase(ESD_SymbolRenamingFlag); + BCase(ESD_RemovableClass); + BCaseMask(ESD_RQ_0, ESD_Mask_RQW); + BCaseMask(ESD_RQ_1, ESD_Mask_RQW); + BCaseMask(ESD_RQ_2, ESD_Mask_RQW); + BCaseMask(ESD_RQ_3, ESD_Mask_RQW); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_TEXTRECORDSTYLE &Value) { + ECase(TXT_RS_Byte); + ECase(TXT_RS_Structured); + ECase(TXT_RS_Unstructured); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDAMODE &Value) { + ECase(ESD_AMODE_None); + ECase(ESD_AMODE_24); + ECase(ESD_AMODE_31); + ECase(ESD_AMODE_ANY); + ECase(ESD_AMODE_64); + ECase(ESD_AMODE_MIN); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDRMODE &Value) { + ECase(ESD_RMODE_None); + ECase(ESD_RMODE_24); + ECase(ESD_RMODE_31); + ECase(ESD_RMODE_64); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDTEXTSTYLE &Value) { + ECase(ESD_TS_ByteOriented); + ECase(ESD_TS_Structured); + ECase(ESD_TS_Unstructured); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDBINDINGALGORITHM &Value) { + ECase(ESD_BA_Concatenate); + ECase(ESD_BA_Merge); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDTASKINGBEHAVIOR &Value) { + ECase(ESD_TA_Unspecified); + ECase(ESD_TA_NonReus); + ECase(ESD_TA_Reus); + ECase(ESD_TA_Rent); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDEXECUTABLE &Value) { + ECase(ESD_EXE_Unspecified); + ECase(ESD_EXE_DATA); + ECase(ESD_EXE_CODE); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDLINKAGETYPE &Value) { + ECase(ESD_LT_OS); + ECase(ESD_LT_XPLink); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDBINDINGSTRENGTH &Value) { + ECase(ESD_BST_Strong); + ECase(ESD_BST_Weak); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDLOADINGBEHAVIOR &Value) { + ECase(ESD_LB_Initial); + ECase(ESD_LB_Deferred); + ECase(ESD_LB_NoLoad); + ECase(ESD_LB_Reserved); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDBINDINGSCOPE &Value) { + ECase(ESD_BSC_Unspecified); + ECase(ESD_BSC_Section); + ECase(ESD_BSC_Module); + ECase(ESD_BSC_Library); + ECase(ESD_BSC_ImportExport); + IO.enumFallback(Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, GOFFYAML::GOFF_ESDALIGNMENT &Value) { + ECase(ESD_ALIGN_Byte); + ECase(ESD_ALIGN_Halfword); + ECase(ESD_ALIGN_Fullword); + ECase(ESD_ALIGN_Doubleword); + ECase(ESD_ALIGN_Quadword); + ECase(ESD_ALIGN_32byte); + ECase(ESD_ALIGN_64byte); + ECase(ESD_ALIGN_128byte); + ECase(ESD_ALIGN_256byte); + ECase(ESD_ALIGN_512byte); + ECase(ESD_ALIGN_1024byte); + ECase(ESD_ALIGN_2Kpage); + ECase(ESD_ALIGN_4Kpage); + IO.enumFallback(Value); +} + +void ScalarBitSetTraits::bitset( + IO &IO, GOFFYAML::GOFF_BAFLAGS &Value) { + BCase(ESD_BA_Movable); + BCase(ESD_BA_ReadOnly); + BCase(ESD_BA_NoPrime); + BCase(ESD_BA_COMMON); + BCase(ESD_BA_Indirect); +} + +void MappingTraits::mapping(IO &IO, GOFFYAML::Symbol &Sym) { + IO.mapRequired("Name", Sym.Name); + IO.mapRequired("Type", Sym.Type); + IO.mapOptional("ID", Sym.ID); + IO.mapOptional("OwnerID", Sym.OwnerID, 0); + IO.mapOptional("Address", Sym.Address, 0); + IO.mapOptional("Length", Sym.Length, 0); + IO.mapOptional("ExtAttrID", Sym.ExtAttrID, 0); + IO.mapOptional("ExtAttrOffset", Sym.ExtAttrOffset, 0); + IO.mapRequired("NameSpace", Sym.NameSpace); + IO.mapOptional("Flags", Sym.Flags, GOFFYAML::GOFF_ESDFlags(0)); + IO.mapOptional("FillByteValue", Sym.FillByteValue, 0); + IO.mapOptional("PSectID", Sym.PSectID, 0); + IO.mapOptional("Priority", Sym.Priority, 0); + IO.mapOptional("Signature", Sym.Signature, 0); + IO.mapOptional("Amode", Sym.Amode, GOFF::ESD_AMODE_None); + IO.mapOptional("Rmode", Sym.Rmode, GOFF::ESD_RMODE_None); + IO.mapOptional("TextStyle", Sym.TextStyle, GOFF::ESD_TS_ByteOriented); + IO.mapOptional("BindingAlgorithm", Sym.BindingAlgorithm, + GOFF::ESD_BA_Concatenate); + IO.mapOptional("TaskingBehavior", Sym.TaskingBehavior, + GOFF::ESD_TA_Unspecified); + IO.mapOptional("Executable", Sym.Executable, GOFF::ESD_EXE_Unspecified); + IO.mapOptional("LinkageType", Sym.LinkageType, GOFF::ESD_LT_OS); + IO.mapOptional("BindingStrength", Sym.BindingStrength, GOFF::ESD_BST_Strong); + IO.mapOptional("LoadingBehavior", Sym.LoadingBehavior, GOFF::ESD_LB_Initial); + IO.mapOptional("BindingScope", Sym.BindingScope, GOFF::ESD_BSC_Unspecified); + IO.mapOptional("Alignment", Sym.Alignment, GOFF::ESD_ALIGN_Byte); + IO.mapOptional("BAFlags", Sym.BAFlags, 0); +} + void MappingTraits::mapping( IO &IO, GOFFYAML::FileHeader &FileHdr) { IO.mapOptional("TargetEnvironment", FileHdr.TargetEnvironment, 0); @@ -37,9 +222,28 @@ void MappingTraits::mapping( FileHdr.TargetSoftwareEnvironment); } +void CustomMappingTraits::inputOne( + IO &IO, StringRef Key, GOFFYAML::RecordPtr &Elem) { + if (Key == "Symbol") { + GOFFYAML::Symbol Sym; + IO.mapRequired("Symbol", Sym); + Elem = std::make_unique(std::move(Sym)); + } +} + +void CustomMappingTraits::output( + IO &IO, GOFFYAML::RecordPtr &Elem) { + if (auto *Sym = dyn_cast(Elem.get())) { + IO.mapRequired("Symbol", *Sym); + } else { + IO.setError("unknown record type"); + } +} + void MappingTraits::mapping(IO &IO, GOFFYAML::Object &Obj) { IO.mapTag("!GOFF", true); IO.mapRequired("FileHeader", Obj.Header); + IO.mapOptional("Records", Obj.Records); } } // namespace yaml diff --git a/llvm/test/tools/yaml2obj/GOFF/basic.yaml b/llvm/test/tools/yaml2obj/GOFF/basic.yaml new file mode 100644 index 0000000000000..4b2b8cba48039 --- /dev/null +++ b/llvm/test/tools/yaml2obj/GOFF/basic.yaml @@ -0,0 +1,58 @@ +# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s + +--- !GOFF +FileHeader: + ArchitectureLevel: 1 +Records: +## Bytes 80-159 +# CHECK: 03 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 04 88 89 7b c3 00 00 00 00 + - Symbol: + Name: 'hi#C' + Type: ESD_ST_SectionDefinition + ID: 1 + OwnerID: 0 + Address: 0 + Length: 0 + NameSpace: ESD_NS_ProgramManagementBinder +# Bytes 160-239 +# CHECK: 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01 +# CHECK-NEXT: 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00 + - Symbol: + Name: 'C_WSA64' + Type: ESD_ST_ElementDefinition + ID: 2 + OwnerID: 1 + NameSpace: ESD_NS_Parts + Flags: [ ESD_FillByteValuePresent, ESD_RQ_1 ] + FillByteValue: 0 + Amode: ESD_AMODE_64 + Rmode: ESD_RMODE_64 + BindingAlgorithm: ESD_BA_Merge + Executable: ESD_EXE_DATA + LoadingBehavior: ESD_LB_Deferred + Alignment: ESD_ALIGN_Doubleword +# Bytes 240-319 +# CHECK: 03 00 00 03 00 00 00 03 00 00 00 02 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 +# CHECK-NEXT: 00 01 24 00 00 00 00 04 88 89 7b e2 00 00 00 00 + - Symbol: + Name: 'hi#S' + Type: ESD_ST_PartReference + ID: 3 + OwnerID: 2 + Address: 0 + Length: 2 + NameSpace: ESD_NS_Parts + LinkageType: ESD_LT_XPLink + Alignment: ESD_ALIGN_Quadword + BindingScope: ESD_BSC_Section + Executable: ESD_EXE_DATA diff --git a/llvm/test/tools/yaml2obj/GOFF/GOFF-header-end.yaml b/llvm/test/tools/yaml2obj/GOFF/header-end.yaml similarity index 100% rename from llvm/test/tools/yaml2obj/GOFF/GOFF-header-end.yaml rename to llvm/test/tools/yaml2obj/GOFF/header-end.yaml diff --git a/llvm/test/tools/yaml2obj/GOFF/GOFF-header-settings.yaml b/llvm/test/tools/yaml2obj/GOFF/header-settings.yaml similarity index 96% rename from llvm/test/tools/yaml2obj/GOFF/GOFF-header-settings.yaml rename to llvm/test/tools/yaml2obj/GOFF/header-settings.yaml index 1971c407199fb..e7495b24527d3 100644 --- a/llvm/test/tools/yaml2obj/GOFF/GOFF-header-settings.yaml +++ b/llvm/test/tools/yaml2obj/GOFF/header-settings.yaml @@ -23,4 +23,4 @@ FileHeader: LanguageProductIdentifier: "" ArchitectureLevel: 1 InternalCCSID: 0 - TargetSoftwareEnvironment: 0 + TargetSoftwareEnvironment: 0 diff --git a/llvm/test/tools/yaml2obj/GOFF/long-symbol.yaml b/llvm/test/tools/yaml2obj/GOFF/long-symbol.yaml new file mode 100644 index 0000000000000..a8318a4d90439 --- /dev/null +++ b/llvm/test/tools/yaml2obj/GOFF/long-symbol.yaml @@ -0,0 +1,91 @@ +## This tests the long symbol name case requiring continuation records. +# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s + +--- !GOFF +FileHeader: + ArchitectureLevel: 1 +Records: +## Bytes 80-159 +## Bits 06-07 of Byte 2 should be set to 01 to indicate that this +## is an "initial record" and it will be continued in the subsequent +## record. +# CHECK: 03 01 00 00 00 00 00 01 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 39 88 89 a3 88 89 a2 89 a2 +## Bytes 160-239 +## Bits 06-07 of Byte 2 are set to 10 to indicate that this is +## a continuation record, and it is not continued in the next +## record. +# CHECK-NEXT: 03 02 00 81 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 +# CHECK-NEXT: a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 +# CHECK-NEXT: a5 85 99 a8 93 96 95 87 a2 a8 94 82 96 93 95 81 +# CHECK-NEXT: 94 85 7b c3 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + - Symbol: + Name: 'hithisisaveryveryveryveryveryveryveryverylongsymbolname#C' + Type: ESD_ST_SectionDefinition + ID: 1 + OwnerID: 0 + Address: 0 + Length: 0 + NameSpace: ESD_NS_ProgramManagementBinder +# CHECK-NEXT: 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01 +# CHECK-NEXT: 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00 + - Symbol: + Name: 'C_WSA64' + Type: ESD_ST_ElementDefinition + ID: 2 + OwnerID: 1 + NameSpace: ESD_NS_Parts + Flags: [ ESD_FillByteValuePresent, ESD_RQ_1 ] + FillByteValue: 0 + Amode: ESD_AMODE_64 + Rmode: ESD_RMODE_64 + BindingAlgorithm: ESD_BA_Merge + Executable: ESD_EXE_DATA + LoadingBehavior: ESD_LB_Deferred + Alignment: ESD_ALIGN_Doubleword +## Symbol spanning 4 records. First record's second byte +## ends in 01 indicating that it is continued. +# CHECK-NEXT: 03 01 00 03 00 00 00 03 00 00 00 01 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 +# CHECK-NEXT: 00 00 02 00 00 00 00 cf 93 96 95 87 a2 a8 94 82 +## Second record's second byte ends in 11 indicating that it +## is continued, and it itself is a continuation. +# CHECK-NEXT: 03 03 00 96 93 95 96 a3 a2 88 96 99 a3 a3 88 89 +# CHECK-NEXT: a2 89 a2 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 +# CHECK-NEXT: 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 +# CHECK-NEXT: 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 +# CHECK-NEXT: 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 +## Third record's second byte ends in 11 indicating that it +## is continued, and it itself is a continuation. +# CHECK-NEXT: 03 03 00 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 +# CHECK-NEXT: 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 +# CHECK-NEXT: 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 99 a8 a5 85 +# CHECK-NEXT: 99 a8 a5 85 99 a8 93 96 95 87 89 95 86 81 83 a3 +# CHECK-NEXT: a3 88 89 a2 89 a2 85 a5 85 95 93 96 95 87 85 99 +## Fourth record's second byte ends in 10 indicating that it +## is not continued, but the record itself is a continuation. +# CHECK-NEXT: 03 02 00 a3 88 81 95 a3 88 85 97 99 85 a5 89 96 +# CHECK-NEXT: a4 a2 a2 a8 94 82 96 93 a6 88 89 83 88 a6 81 a2 +# CHECK-NEXT: 98 a4 89 a3 85 93 96 95 87 81 93 99 85 81 84 a8 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + - Symbol: + Name: 'longsymbolnotshortthisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylonginfactthisisevenlongerthantheprevioussymbolwhichwasquitelongalready' + Type: ESD_ST_PartReference + ID: 3 + OwnerID: 1 + Address: 0 + Length: 4 + NameSpace: ESD_NS_Parts + Alignment: ESD_ALIGN_Fullword + Executable: ESD_EXE_DATA diff --git a/llvm/test/tools/yaml2obj/GOFF/GOFF-no-header.yaml b/llvm/test/tools/yaml2obj/GOFF/no-header.yaml similarity index 100% rename from llvm/test/tools/yaml2obj/GOFF/GOFF-no-header.yaml rename to llvm/test/tools/yaml2obj/GOFF/no-header.yaml diff --git a/llvm/test/tools/yaml2obj/GOFF/one-symbol.yaml b/llvm/test/tools/yaml2obj/GOFF/one-symbol.yaml new file mode 100644 index 0000000000000..c3f61b2145da4 --- /dev/null +++ b/llvm/test/tools/yaml2obj/GOFF/one-symbol.yaml @@ -0,0 +1,38 @@ +## Test for 1 symbol case. +# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s + +## Verify that GOFF Header is correct. +# CHECK: 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +## Verify that the symbol is written correctly. +# CHECK-NEXT: 03 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 01 a7 00 00 00 00 00 00 00 + +## Verify GOFF Module end. +# CHECK-NEXT: 03 40 00 00 00 00 00 00 00 00 00 03 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +--- !GOFF +FileHeader: + ArchitectureLevel: 1 +Records: + - Symbol: + Name: 'x' + Type: ESD_ST_ElementDefinition + ID: 1 + OwnerID: 0 + Address: 0 + Length: 0 + NameSpace: ESD_NS_NormalName + Flags: [] + FillByteValue: 0 diff --git a/llvm/test/tools/yaml2obj/GOFF/symbol-all-fields.yaml b/llvm/test/tools/yaml2obj/GOFF/symbol-all-fields.yaml new file mode 100644 index 0000000000000..aeb924474a94c --- /dev/null +++ b/llvm/test/tools/yaml2obj/GOFF/symbol-all-fields.yaml @@ -0,0 +1,55 @@ +## This tests a symbol where all required and optional fields are set. +# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s + +## Verify that GOFF Header is correct. +# CHECK: 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +## Verify that the symbol is written correctly. +# CHECK-NEXT: 03 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 01 a7 00 00 00 00 00 00 00 + +## Verify GOFF Module end. +# CHECK-NEXT: 03 40 00 00 00 00 00 00 00 00 00 03 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +--- !GOFF +FileHeader: + ArchitectureLevel: 1 +Records: + - Symbol: + Name: 'x' + Type: ESD_ST_ElementDefinition + ID: 1 + OwnerID: 0 + Address: 0 + Length: 0 + ExtAttrID: 0 + ExtAttrOffset: 0 + NameSpace: ESD_NS_NormalName + Flags: [] + FillByteValue: 0 + PSectID: 0 + Priority: 0 + Signature: 0 + Amode: 0 + Rmode: 0 + TextStyle: 0 + BindingAlgorithm: 0 + TaskingBehavior: 0 + Executable: 0 + LinkageType: 0 + BindingStrength: 0 + LoadingBehavior: 0 + BindingScope: 0 + Alignment: 0 + BAFlags: [] diff --git a/llvm/test/tools/yaml2obj/GOFF/symbol-required.yaml b/llvm/test/tools/yaml2obj/GOFF/symbol-required.yaml new file mode 100644 index 0000000000000..1cb2cb6c32d00 --- /dev/null +++ b/llvm/test/tools/yaml2obj/GOFF/symbol-required.yaml @@ -0,0 +1,32 @@ +## This tests a symbol where none of the optional fields are set. +# RUN: yaml2obj %s | od -v -An -tx1 | FileCheck --ignore-case %s + +## Verify that GOFF Header is correct. +# CHECK: 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +## Verify that the symbol is written correctly. +# CHECK-NEXT: 03 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 01 a7 00 00 00 00 00 00 00 + +## Verify GOFF Module end. +# CHECK-NEXT: 03 40 00 00 00 00 00 00 00 00 00 03 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# CHECK-NEXT: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +--- !GOFF +FileHeader: + ArchitectureLevel: 1 +Records: + - Symbol: + Name: 'x' + Type: ESD_ST_ElementDefinition + NameSpace: ESD_NS_NormalName