[llvm] [XCOFF][obj2yaml] Support SymbolAlignmentAndType as 2 separate fields in YAML. (PR #76828)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 09:13:18 PST 2024


https://github.com/stephenpeckham updated https://github.com/llvm/llvm-project/pull/76828

>From 5787f2cddb3bc113cbc478f2c333af2b66d367f1 Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Wed, 3 Jan 2024 10:11:15 -0500
Subject: [PATCH 1/4] [tools] Support SymbolAlignmentAndType as 2 separate
 fields in YAML files.

---
 llvm/include/llvm/ObjectYAML/XCOFFYAML.h        |  7 +++++++
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp            | 13 +++++++++++--
 llvm/lib/ObjectYAML/XCOFFYAML.cpp               | 15 ++++++++++++++-
 llvm/test/tools/obj2yaml/XCOFF/aix.yaml         | 12 ++++++++----
 llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml | 15 ++++++++++-----
 llvm/tools/obj2yaml/xcoff2yaml.cpp              | 12 +++++++-----
 6 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
index f1e821fe5fa369f..dd359ac8e53dd3a 100644
--- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
@@ -121,6 +121,9 @@ struct CsectAuxEnt : AuxSymbolEnt {
   // Common fields for both XCOFF32 and XCOFF64.
   std::optional<uint32_t> ParameterHashIndex;
   std::optional<uint16_t> TypeChkSectNum;
+  std::optional<XCOFF::SymbolType> SymbolType;
+  std::optional<uint8_t> SymbolAlignment;
+  // The two previous values can be encoded as a single value.
   std::optional<uint8_t> SymbolAlignmentAndType;
   std::optional<XCOFF::StorageMappingClass> StorageMappingClass;
 
@@ -237,6 +240,10 @@ template <> struct ScalarEnumerationTraits<XCOFF::StorageMappingClass> {
   static void enumeration(IO &IO, XCOFF::StorageMappingClass &Value);
 };
 
+template <> struct ScalarEnumerationTraits<XCOFF::SymbolType> {
+  static void enumeration(IO &IO, XCOFF::SymbolType &Value);
+};
+
 template <> struct ScalarEnumerationTraits<XCOFF::CFileStringType> {
   static void enumeration(IO &IO, XCOFF::CFileStringType &Type);
 };
diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index ccf768c06aebfe6..327440c6b871036 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -23,6 +23,7 @@
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
+using namespace llvm::object;
 
 namespace {
 
@@ -525,11 +526,19 @@ bool XCOFFWriter::writeRelocations() {
 }
 
 void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
+  uint8_t SymAlignAndType = AuxSym.SymbolAlignmentAndType.value_or(0);
+  if (AuxSym.SymbolType)
+    SymAlignAndType = (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolTypeMask) |
+                      *AuxSym.SymbolType;
+  if (AuxSym.SymbolAlignment)
+    SymAlignAndType =
+        (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolAlignmentMask) |
+        (*AuxSym.SymbolAlignment << XCOFFCsectAuxRef::SymbolAlignmentBitOffset);
   if (Is64Bit) {
     W.write<uint32_t>(AuxSym.SectionOrLengthLo.value_or(0));
     W.write<uint32_t>(AuxSym.ParameterHashIndex.value_or(0));
     W.write<uint16_t>(AuxSym.TypeChkSectNum.value_or(0));
-    W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.value_or(0));
+    W.write<uint8_t>(SymAlignAndType);
     W.write<uint8_t>(AuxSym.StorageMappingClass.value_or(XCOFF::XMC_PR));
     W.write<uint32_t>(AuxSym.SectionOrLengthHi.value_or(0));
     W.write<uint8_t>(0);
@@ -538,7 +547,7 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
     W.write<uint32_t>(AuxSym.SectionOrLength.value_or(0));
     W.write<uint32_t>(AuxSym.ParameterHashIndex.value_or(0));
     W.write<uint16_t>(AuxSym.TypeChkSectNum.value_or(0));
-    W.write<uint8_t>(AuxSym.SymbolAlignmentAndType.value_or(0));
+    W.write<uint8_t>(SymAlignAndType);
     W.write<uint8_t>(AuxSym.StorageMappingClass.value_or(XCOFF::XMC_PR));
     W.write<uint32_t>(AuxSym.StabInfoIndex.value_or(0));
     W.write<uint16_t>(AuxSym.StabSectNum.value_or(0));
diff --git a/llvm/lib/ObjectYAML/XCOFFYAML.cpp b/llvm/lib/ObjectYAML/XCOFFYAML.cpp
index 398b09c72170baa..a1eea621a1056e1 100644
--- a/llvm/lib/ObjectYAML/XCOFFYAML.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFYAML.cpp
@@ -127,6 +127,16 @@ void ScalarEnumerationTraits<XCOFF::StorageMappingClass>::enumeration(
 #undef ECase
 }
 
+void ScalarEnumerationTraits<XCOFF::SymbolType>::enumeration(
+    IO &IO, XCOFF::SymbolType &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+  ECase(XTY_ER);
+  ECase(XTY_SD);
+  ECase(XTY_LD);
+  ECase(XTY_CM);
+#undef ECase
+}
+
 void ScalarEnumerationTraits<XCOFFYAML::AuxSymbolType>::enumeration(
     IO &IO, XCOFFYAML::AuxSymbolType &Type) {
 #define ECase(X) IO.enumCase(Type, #X, XCOFFYAML::X)
@@ -229,6 +239,8 @@ static void auxSymMapping(IO &IO, XCOFFYAML::CsectAuxEnt &AuxSym, bool Is64) {
   IO.mapOptional("ParameterHashIndex", AuxSym.ParameterHashIndex);
   IO.mapOptional("TypeChkSectNum", AuxSym.TypeChkSectNum);
   IO.mapOptional("SymbolAlignmentAndType", AuxSym.SymbolAlignmentAndType);
+  IO.mapOptional("SymbolType", AuxSym.SymbolType);
+  IO.mapOptional("SymbolAlignment", AuxSym.SymbolAlignment);
   IO.mapOptional("StorageMappingClass", AuxSym.StorageMappingClass);
   if (Is64) {
     IO.mapOptional("SectionOrLengthLo", AuxSym.SectionOrLengthLo);
@@ -350,7 +362,8 @@ void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
   IO.mapOptional("AuxEntries", S.AuxEntries);
 }
 
-void MappingTraits<XCOFFYAML::StringTable>::mapping(IO &IO, XCOFFYAML::StringTable &Str) {
+void MappingTraits<XCOFFYAML::StringTable>::mapping(
+    IO &IO, XCOFFYAML::StringTable &Str) {
   IO.mapOptional("ContentSize", Str.ContentSize);
   IO.mapOptional("Length", Str.Length);
   IO.mapOptional("Strings", Str.Strings);
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
index fbd5fa0629d10bd..9f2f68b646b6f4f 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
@@ -56,7 +56,8 @@
 # CHECK32-NEXT:       - Type:            AUX_CSECT
 # CHECK32-NEXT:         ParameterHashIndex: 0
 # CHECK32-NEXT:         TypeChkSectNum:  0
-# CHECK32-NEXT:         SymbolAlignmentAndType: 0
+# CHECK32-NEXT:         SymbolType:      XTY_ER
+# CHECK32-NEXT:         SymbolAlignment: 0
 # CHECK32-NEXT:         StorageMappingClass: XMC_PR
 # CHECK32-NEXT:         SectionOrLength: 0
 # CHECK32-NEXT:         StabInfoIndex:   0
@@ -71,7 +72,8 @@
 # CHECK32-NEXT:       - Type:            AUX_CSECT
 # CHECK32-NEXT:         ParameterHashIndex: 0
 # CHECK32-NEXT:         TypeChkSectNum:  0
-# CHECK32-NEXT:         SymbolAlignmentAndType: 0
+# CHECK32-NEXT:         SymbolType:      XTY_ER
+# CHECK32-NEXT:         SymbolAlignment: 0
 # CHECK32-NEXT:         StorageMappingClass: XMC_PR
 # CHECK32-NEXT:         SectionOrLength: 0
 # CHECK32-NEXT:         StabInfoIndex:   0
@@ -128,7 +130,8 @@
 # CHECK64-NEXT:       - Type:            AUX_CSECT
 # CHECK64-NEXT:         ParameterHashIndex: 0
 # CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolAlignmentAndType: 0
+# CHECK64-NEXT:         SymbolType:      XTY_ER
+# CHECK64-NEXT:         SymbolAlignment: 0
 # CHECK64-NEXT:         StorageMappingClass: XMC_PR
 # CHECK64-NEXT:         SectionOrLengthLo: 0
 # CHECK64-NEXT:         SectionOrLengthHi: 0
@@ -142,7 +145,8 @@
 # CHECK64-NEXT:       - Type:            AUX_CSECT
 # CHECK64-NEXT:         ParameterHashIndex: 0
 # CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolAlignmentAndType: 0
+# CHECK64-NEXT:         SymbolType:      XTY_ER
+# CHECK64-NEXT:         SymbolAlignment: 0
 # CHECK64-NEXT:         StorageMappingClass: XMC_PR
 # CHECK64-NEXT:         SectionOrLengthLo: 0
 # CHECK64-NEXT:         SectionOrLengthHi: 0
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml b/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
index 7f93b8dae0ca9b5..2260bb07749898f 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
@@ -34,7 +34,8 @@
 # CHECK32-NEXT:       - Type:            AUX_CSECT
 # CHECK32-NEXT:         ParameterHashIndex: 1
 # CHECK32-NEXT:         TypeChkSectNum:  2
-# CHECK32-NEXT:         SymbolAlignmentAndType: 41
+# CHECK32-NEXT:         SymbolType: XTY_SD
+# CHECK32-NEXT:         SymbolAlignment: 5
 # CHECK32-NEXT:         StorageMappingClass: XMC_PR
 # CHECK32-NEXT:         SectionOrLength: 3
 # CHECK32-NEXT:         StabInfoIndex:   4
@@ -54,7 +55,8 @@
 # CHECK32-NEXT:       - Type:            AUX_CSECT
 # CHECK32-NEXT:         ParameterHashIndex: 1
 # CHECK32-NEXT:         TypeChkSectNum:  2
-# CHECK32-NEXT:         SymbolAlignmentAndType: 17
+# CHECK32-NEXT:         SymbolType: XTY_SD
+# CHECK32-NEXT:         SymbolAlignment: 2
 # CHECK32-NEXT:         StorageMappingClass: XMC_PR
 # CHECK32-NEXT:         SectionOrLength: 4
 # CHECK32-NEXT:         StabInfoIndex:   5
@@ -105,7 +107,8 @@ Symbols:
       - Type:               AUX_CSECT
         ParameterHashIndex: 1
         TypeChkSectNum:     2
-        SymbolAlignmentAndType: 41
+        SymbolAlignment: 5
+        SymbolType: XTY_SD
         SectionOrLength:    3
         StabInfoIndex:      4
         StabSectNum:        5
@@ -174,7 +177,8 @@ Symbols:
 # CHECK64-NEXT:       - Type:            AUX_CSECT
 # CHECK64-NEXT:         ParameterHashIndex: 1
 # CHECK64-NEXT:         TypeChkSectNum:  2
-# CHECK64-NEXT:         SymbolAlignmentAndType: 41
+# CHECK64-NEXT:         SymbolType: XTY_SD
+# CHECK64-NEXT:         SymbolAlignment: 5
 # CHECK64-NEXT:         StorageMappingClass: XMC_PR
 # CHECK64-NEXT:         SectionOrLengthLo: 3
 # CHECK64-NEXT:         SectionOrLengthHi: 4
@@ -196,7 +200,8 @@ Symbols:
 # CHECK64-NEXT:       - Type:            AUX_CSECT
 # CHECK64-NEXT:         ParameterHashIndex: 1
 # CHECK64-NEXT:         TypeChkSectNum:  2
-# CHECK64-NEXT:         SymbolAlignmentAndType: 17
+# CHECK64-NEXT:         SymbolType: XTY_SD
+# CHECK64-NEXT:         SymbolAlignment: 2
 # CHECK64-NEXT:         StorageMappingClass: XMC_PR
 # CHECK64-NEXT:         SectionOrLengthLo: 3
 # CHECK64-NEXT:         SectionOrLengthHi: 4
diff --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp
index f7c2bae74798951..e426b645cbeff66 100644
--- a/llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -37,7 +37,7 @@ class XCOFFDumper {
   Error dumpAuxSyms(XCOFFYAML::Symbol &Sym, const XCOFFSymbolRef &SymbolEntRef);
   void dumpFuncAuxSym(XCOFFYAML::Symbol &Sym, const uintptr_t AuxAddress);
   void dumpExpAuxSym(XCOFFYAML::Symbol &Sym, const uintptr_t AuxAddress);
-  void dumpCscetAuxSym(XCOFFYAML::Symbol &Sym,
+  void dumpCsectAuxSym(XCOFFYAML::Symbol &Sym,
                        const object::XCOFFCsectAuxRef &AuxEntPtr);
 
 public:
@@ -204,12 +204,14 @@ void XCOFFDumper::dumpExpAuxSym(XCOFFYAML::Symbol &Sym,
       std::make_unique<XCOFFYAML::ExcpetionAuxEnt>(ExceptAuxSym));
 }
 
-void XCOFFDumper::dumpCscetAuxSym(XCOFFYAML::Symbol &Sym,
+void XCOFFDumper::dumpCsectAuxSym(XCOFFYAML::Symbol &Sym,
                                   const object::XCOFFCsectAuxRef &AuxEntPtr) {
   XCOFFYAML::CsectAuxEnt CsectAuxSym;
   CsectAuxSym.ParameterHashIndex = AuxEntPtr.getParameterHashIndex();
   CsectAuxSym.TypeChkSectNum = AuxEntPtr.getTypeChkSectNum();
-  CsectAuxSym.SymbolAlignmentAndType = AuxEntPtr.getSymbolAlignmentAndType();
+  CsectAuxSym.SymbolAlignment = AuxEntPtr.getAlignmentLog2();
+  CsectAuxSym.SymbolType =
+      static_cast<XCOFF::SymbolType>(AuxEntPtr.getSymbolType());
   CsectAuxSym.StorageMappingClass = AuxEntPtr.getStorageMappingClass();
 
   if (Obj.is64Bit()) {
@@ -237,7 +239,7 @@ Error XCOFFDumper::dumpAuxSyms(XCOFFYAML::Symbol &Sym,
   for (uint8_t I = 1; I <= Sym.NumberOfAuxEntries; ++I) {
 
     if (I == Sym.NumberOfAuxEntries && !Obj.is64Bit()) {
-      dumpCscetAuxSym(Sym, CsectAuxRef);
+      dumpCsectAuxSym(Sym, CsectAuxRef);
       return Error::success();
     }
 
@@ -247,7 +249,7 @@ Error XCOFFDumper::dumpAuxSyms(XCOFFYAML::Symbol &Sym,
     if (Obj.is64Bit()) {
       XCOFF::SymbolAuxType Type = *Obj.getSymbolAuxType(AuxAddress);
       if (Type == XCOFF::SymbolAuxType::AUX_CSECT)
-        dumpCscetAuxSym(Sym, CsectAuxRef);
+        dumpCsectAuxSym(Sym, CsectAuxRef);
       else if (Type == XCOFF::SymbolAuxType::AUX_FCN)
         dumpFuncAuxSym(Sym, AuxAddress);
       else if (Type == XCOFF::SymbolAuxType::AUX_EXCEPT)

>From dcf3db363ae0e5dc17d1319b90ae3df1214af7e6 Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Thu, 4 Jan 2024 14:39:05 -0500
Subject: [PATCH 2/4] Add new test case.

---
 .../tools/obj2yaml/XCOFF/aux-aligntype.yaml   | 209 ++++++++++++++++++
 .../tools/obj2yaml/XCOFF/aux-symbols.yaml     |   3 +-
 2 files changed, 210 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml

diff --git a/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
new file mode 100644
index 000000000000000..39eacea0fdb98a3
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
@@ -0,0 +1,209 @@
+## Check that obj2yaml can parse SymbolAlignmentAndType, SymbolAlignment, and SymbolType.
+
+# RUN: yaml2obj %s --docnum=1 -o %t32
+# RUN: obj2yaml %t32 | FileCheck %s --check-prefix=CHECK32
+
+# CHECK32:      --- !XCOFF
+# CHECK32-NEXT: FileHeader:
+# CHECK32-NEXT:   MagicNumber:     0x1DF
+# CHECK32-NEXT:   NumberOfSections: 0
+# CHECK32-NEXT:   CreationTime:    0
+# CHECK32-NEXT:   OffsetToSymbolTable: 0x14
+# CHECK32-NEXT:   EntriesInSymbolTable: 10
+# CHECK32-NEXT:   AuxiliaryHeaderSize: 0
+# CHECK32-NEXT:   Flags:           0x0
+# CHECK32-NEXT: Symbols:
+# CHECK32:       - Name:            .fcn1
+# CHECK32-NEXT:    Value:           0x0
+# CHECK32-NEXT:    Section:         N_UNDEF
+# CHECK32-NEXT:    Type:            0x0
+# CHECK32-NEXT:    StorageClass:    C_EXT
+# CHECK32-NEXT:    NumberOfAuxEntries: 1
+# CHECK32-NEXT:    AuxEntries:
+# CHECK32-NEXT:      - Type:            AUX_CSECT
+# CHECK32-NEXT:        ParameterHashIndex: 0
+# CHECK32-NEXT:        TypeChkSectNum:  0
+# CHECK32-NEXT:        SymbolType:      XTY_SD
+# CHECK32-NEXT:        SymbolAlignment: 4
+# CHECK32-NEXT:        StorageMappingClass: XMC_PR
+# CHECK32:       - Name:            .fcn2
+# CHECK32-NEXT:    Value:           0x0
+# CHECK32-NEXT:    Section:         N_UNDEF
+# CHECK32-NEXT:    Type:            0x0
+# CHECK32-NEXT:    StorageClass:    C_EXT
+# CHECK32-NEXT:    NumberOfAuxEntries: 1
+# CHECK32-NEXT:    AuxEntries:
+# CHECK32-NEXT:      - Type:            AUX_CSECT
+# CHECK32-NEXT:        ParameterHashIndex: 0
+# CHECK32-NEXT:        TypeChkSectNum:  0
+# CHECK32-NEXT:        SymbolType:      XTY_SD
+# CHECK32-NEXT:        SymbolAlignment: 2
+# CHECK32-NEXT:        StorageMappingClass: XMC_PR
+# CHECK32:       - Name:            .fcn3
+# CHECK32-NEXT:    Value:           0x0
+# CHECK32-NEXT:    Section:         N_UNDEF
+# CHECK32-NEXT:    Type:            0x0
+# CHECK32-NEXT:    StorageClass:    C_EXT
+# CHECK32-NEXT:    NumberOfAuxEntries: 1
+# CHECK32-NEXT:    AuxEntries:
+# CHECK32-NEXT:      - Type:            AUX_CSECT
+# CHECK32-NEXT:        ParameterHashIndex: 0
+# CHECK32-NEXT:        TypeChkSectNum:  0
+# CHECK32-NEXT:        SymbolType:      XTY_SD
+# CHECK32-NEXT:        SymbolAlignment: 0
+# CHECK32-NEXT:        StorageMappingClass: XMC_PR
+# CHECK32:       - Name:            .fcn4
+# CHECK32-NEXT:    Value:           0x0
+# CHECK32-NEXT:    Section:         N_UNDEF
+# CHECK32-NEXT:    Type:            0x0
+# CHECK32-NEXT:    StorageClass:    C_EXT
+# CHECK32-NEXT:    NumberOfAuxEntries: 1
+# CHECK32-NEXT:    AuxEntries:
+# CHECK32-NEXT:      - Type:            AUX_CSECT
+# CHECK32-NEXT:        ParameterHashIndex: 0
+# CHECK32-NEXT:        TypeChkSectNum:  0
+# CHECK32-NEXT:        SymbolType:      XTY_ER
+# CHECK32-NEXT:        SymbolAlignment: 5
+# CHECK32-NEXT:        StorageMappingClass: XMC_PR
+
+--- !XCOFF
+FileHeader:
+  MagicNumber: 0x1DF
+Symbols:
+  - StorageClass:    C_FILE
+    AuxEntries:
+      - Type:             AUX_FILE
+        FileNameOrString: FileName
+        FileStringType:   XFT_CD
+  - StorageClass:    C_EXT
+    Name:               .fcn1
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignmentAndType: 17
+        SymbolAlignment: 4
+        SectionOrLength:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn2
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignmentAndType: 18
+        SymbolType: XTY_SD
+        SectionOrLength:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn3
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolType: XTY_SD
+        SectionOrLength:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn4
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignment: 5
+        SectionOrLength:    4
+
+# RUN: yaml2obj %s --docnum=2 -o %t64
+# RUN: obj2yaml %t64 | FileCheck %s --check-prefix=CHECK64
+#
+# CHECK64:      --- !XCOFF
+# CHECK64-NEXT: FileHeader:
+# CHECK64-NEXT:   MagicNumber:     0x1F7
+# CHECK64-NEXT:   NumberOfSections: 0
+# CHECK64-NEXT:   CreationTime:    0
+# CHECK64-NEXT:   OffsetToSymbolTable: 0x18
+# CHECK64-NEXT:   EntriesInSymbolTable: 10
+# CHECK64-NEXT:   AuxiliaryHeaderSize: 0
+# CHECK64-NEXT:   Flags:           0x0
+# CHECK64-NEXT: Symbols:
+# CHECK64:        - Name:            .fcn1
+# CHECK64-NEXT:     Value:           0x0
+# CHECK64-NEXT:     Section:         N_UNDEF
+# CHECK64-NEXT:     Type:            0x0
+# CHECK64-NEXT:     StorageClass:    C_EXT
+# CHECK64-NEXT:     NumberOfAuxEntries: 1
+# CHECK64-NEXT:     AuxEntries:
+# CHECK64-NEXT:       - Type:            AUX_CSECT
+# CHECK64-NEXT:         ParameterHashIndex: 0
+# CHECK64-NEXT:         TypeChkSectNum:  0
+# CHECK64-NEXT:         SymbolType:      XTY_SD
+# CHECK64-NEXT:         SymbolAlignment: 4
+# CHECK64-NEXT:         StorageMappingClass: XMC_PR
+# CHECK64-NEXT:         SectionOrLengthLo: 4
+# CHECK64:        - Name:            .fcn2
+# CHECK64-NEXT:     Value:           0x0
+# CHECK64-NEXT:     Section:         N_UNDEF
+# CHECK64-NEXT:     Type:            0x0
+# CHECK64-NEXT:     StorageClass:    C_EXT
+# CHECK64-NEXT:     NumberOfAuxEntries: 1
+# CHECK64-NEXT:     AuxEntries:
+# CHECK64-NEXT:       - Type:            AUX_CSECT
+# CHECK64-NEXT:         ParameterHashIndex: 0
+# CHECK64-NEXT:         TypeChkSectNum:  0
+# CHECK64-NEXT:         SymbolType:      XTY_SD
+# CHECK64-NEXT:         SymbolAlignment: 2
+# CHECK64-NEXT:         StorageMappingClass: XMC_PR
+# CHECK64-NEXT:         SectionOrLengthLo: 4
+# CHECK64:        - Name:            .fcn3
+# CHECK64-NEXT:     Value:           0x0
+# CHECK64-NEXT:     Section:         N_UNDEF
+# CHECK64-NEXT:     Type:            0x0
+# CHECK64-NEXT:     StorageClass:    C_EXT
+# CHECK64-NEXT:     NumberOfAuxEntries: 1
+# CHECK64-NEXT:     AuxEntries:
+# CHECK64-NEXT:       - Type:            AUX_CSECT
+# CHECK64-NEXT:         ParameterHashIndex: 0
+# CHECK64-NEXT:         TypeChkSectNum:  0
+# CHECK64-NEXT:         SymbolType:      XTY_SD
+# CHECK64-NEXT:         SymbolAlignment: 0
+# CHECK64-NEXT:         StorageMappingClass: XMC_PR
+# CHECK64-NEXT:         SectionOrLengthLo: 4
+# CHECK64:        - Name:            .fcn4
+# CHECK64-NEXT:     Value:           0x0
+# CHECK64-NEXT:     Section:         N_UNDEF
+# CHECK64-NEXT:     Type:            0x0
+# CHECK64-NEXT:     StorageClass:    C_EXT
+# CHECK64-NEXT:     NumberOfAuxEntries: 1
+# CHECK64-NEXT:     AuxEntries:
+# CHECK64-NEXT:       - Type:            AUX_CSECT
+# CHECK64-NEXT:         ParameterHashIndex: 0
+# CHECK64-NEXT:         TypeChkSectNum:  0
+# CHECK64-NEXT:         SymbolType:      XTY_ER
+# CHECK64-NEXT:         SymbolAlignment: 5
+# CHECK64-NEXT:         StorageMappingClass: XMC_PR
+# CHECK64-NEXT:         SectionOrLengthLo: 4
+
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1F7
+Symbols:
+  - StorageClass:    C_FILE
+    AuxEntries:
+      - Type:             AUX_FILE
+        FileNameOrString: FileName
+        FileStringType:   XFT_CD
+  - StorageClass:    C_EXT
+    Name:               .fcn1
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignmentAndType: 17
+        SymbolAlignment: 4
+        SectionOrLengthLo:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn2
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignmentAndType: 18
+        SymbolType: XTY_SD
+        SectionOrLengthLo:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn3
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolType: XTY_SD
+        SectionOrLengthLo:    4
+  - StorageClass:    C_EXT
+    Name:               .fcn4
+    AuxEntries:
+      - Type:               AUX_CSECT
+        SymbolAlignment: 5
+        SectionOrLengthLo:    4
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml b/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
index 2260bb07749898f..8155ac1acd186b6 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aux-symbols.yaml
@@ -107,8 +107,7 @@ Symbols:
       - Type:               AUX_CSECT
         ParameterHashIndex: 1
         TypeChkSectNum:     2
-        SymbolAlignment: 5
-        SymbolType: XTY_SD
+        SymbolAlignmentAndType: 41
         SectionOrLength:    3
         StabInfoIndex:      4
         StabSectNum:        5

>From 6c1c67df31f814bd824889f315acd9d512bacdfc Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Mon, 8 Jan 2024 13:40:15 -0500
Subject: [PATCH 3/4] Add code and testcase for checking for invalid alignment

---
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp          |  72 +++---
 .../tools/obj2yaml/XCOFF/aux-aligntype.yaml   | 228 +++++-------------
 2 files changed, 102 insertions(+), 198 deletions(-)

diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index 327440c6b871036..cfda91ba7d3159c 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -57,14 +57,14 @@ class XCOFFWriter {
   bool writeSymbols();
   void writeStringTable();
 
-  void writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
-  void writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);
-  void writeAuxSymbol(const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym);
+  bool writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym);
+  bool writeAuxSymbol(const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym);
 
   XCOFFYAML::Object &Obj;
   bool Is64Bit = false;
@@ -525,15 +525,25 @@ bool XCOFFWriter::writeRelocations() {
   return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
   uint8_t SymAlignAndType = AuxSym.SymbolAlignmentAndType.value_or(0);
   if (AuxSym.SymbolType)
     SymAlignAndType = (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolTypeMask) |
                       *AuxSym.SymbolType;
-  if (AuxSym.SymbolAlignment)
+  if (AuxSym.SymbolAlignment) {
+    const uint8_t ShiftedSymbolAlignmentMask =
+        XCOFFCsectAuxRef::SymbolAlignmentMask >>
+        XCOFFCsectAuxRef::SymbolAlignmentBitOffset;
+
+    if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {
+      ErrHandler("Symbol alignment must be less than " +
+                 Twine(1 + ShiftedSymbolAlignmentMask));
+      return false;
+    }
     SymAlignAndType =
         (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolAlignmentMask) |
         (*AuxSym.SymbolAlignment << XCOFFCsectAuxRef::SymbolAlignmentBitOffset);
+  }
   if (Is64Bit) {
     W.write<uint32_t>(AuxSym.SectionOrLengthLo.value_or(0));
     W.write<uint32_t>(AuxSym.ParameterHashIndex.value_or(0));
@@ -552,18 +562,20 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
     W.write<uint32_t>(AuxSym.StabInfoIndex.value_or(0));
     W.write<uint16_t>(AuxSym.StabSectNum.value_or(0));
   }
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::ExcpetionAuxEnt &AuxSym) {
   assert(Is64Bit && "can't write the exception auxiliary symbol for XCOFF32");
   W.write<uint64_t>(AuxSym.OffsetToExceptionTbl.value_or(0));
   W.write<uint32_t>(AuxSym.SizeOfFunction.value_or(0));
   W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.value_or(0));
   W.write<uint8_t>(0);
   W.write<uint8_t>(XCOFF::AUX_EXCEPT);
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
   if (Is64Bit) {
     W.write<uint64_t>(AuxSym.PtrToLineNum.value_or(0));
     W.write<uint32_t>(AuxSym.SizeOfFunction.value_or(0));
@@ -577,9 +589,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FunctionAuxEnt &AuxSym) {
     W.write<uint32_t>(AuxSym.SymIdxOfNextBeyond.value_or(0));
     W.OS.write_zeros(2);
   }
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
   StringRef FileName = AuxSym.FileNameOrString.value_or("");
   if (nameShouldBeInStringTable(FileName)) {
     W.write<int32_t>(0);
@@ -595,9 +608,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::FileAuxEnt &AuxSym) {
   } else {
     W.OS.write_zeros(3);
   }
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
   if (Is64Bit) {
     W.write<uint32_t>(AuxSym.LineNum.value_or(0));
     W.OS.write_zeros(13);
@@ -608,9 +622,10 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::BlockAuxEnt &AuxSym) {
     W.write<uint16_t>(AuxSym.LineNumLo.value_or(0));
     W.OS.write_zeros(12);
   }
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
   if (Is64Bit) {
     W.write<uint64_t>(AuxSym.LengthOfSectionPortion.value_or(0));
     W.write<uint64_t>(AuxSym.NumberOfRelocEnt.value_or(0));
@@ -622,34 +637,36 @@ void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForDWARF &AuxSym) {
     W.write<uint32_t>(AuxSym.NumberOfRelocEnt.value_or(0));
     W.OS.write_zeros(6);
   }
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {
+bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::SectAuxEntForStat &AuxSym) {
   assert(!Is64Bit && "can't write the stat auxiliary symbol for XCOFF64");
   W.write<uint32_t>(AuxSym.SectionLength.value_or(0));
   W.write<uint16_t>(AuxSym.NumberOfRelocEnt.value_or(0));
   W.write<uint16_t>(AuxSym.NumberOfLineNum.value_or(0));
   W.OS.write_zeros(10);
+  return true;
 }
 
-void XCOFFWriter::writeAuxSymbol(
+bool XCOFFWriter::writeAuxSymbol(
     const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym) {
   if (auto AS = dyn_cast<XCOFFYAML::CsectAuxEnt>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::FunctionAuxEnt>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::ExcpetionAuxEnt>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::FileAuxEnt>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::BlockAuxEnt>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForDWARF>(AuxSym.get()))
-    writeAuxSymbol(*AS);
+    return writeAuxSymbol(*AS);
   else if (auto AS = dyn_cast<XCOFFYAML::SectAuxEntForStat>(AuxSym.get()))
-    writeAuxSymbol(*AS);
-  else
-    llvm_unreachable("unknown auxiliary symbol type");
+    return writeAuxSymbol(*AS);
+  llvm_unreachable("unknown auxiliary symbol type");
+  return false;
 }
 
 bool XCOFFWriter::writeSymbols() {
@@ -707,7 +724,8 @@ bool XCOFFWriter::writeSymbols() {
     } else {
       for (const std::unique_ptr<XCOFFYAML::AuxSymbolEnt> &AuxSym :
            YamlSym.AuxEntries) {
-        writeAuxSymbol(AuxSym);
+        if (!writeAuxSymbol(AuxSym))
+          return false;
       }
       // Pad with zeros.
       if (NumOfAuxSym > YamlSym.AuxEntries.size())
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
index 39eacea0fdb98a3..4a9d99ef012f475 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
@@ -1,177 +1,82 @@
 ## Check that obj2yaml can parse SymbolAlignmentAndType, SymbolAlignment, and SymbolType.
+## If either SymbolAlignment or SymbolType are specified along with SymbolAligmentAndType,
+## their values override the corresponding portions of SymbolAligmentAndType.
 
-# RUN: yaml2obj %s --docnum=1 -o %t32
-# RUN: obj2yaml %t32 | FileCheck %s --check-prefix=CHECK32
+# RUN: yaml2obj %s --docnum=1 -DMAGIC=0x01DF -DSectionOrLength=SectionOrLength -o %t32
+# RUN: obj2yaml %t32 | FileCheck %s --check-prefix=CHECK
+# RUN: yaml2obj %s --docnum=1 -DMAGIC=0x01F7 -DSectionOrLength=SectionOrLengthLo -o %t64
+# RUN: obj2yaml %t64 | FileCheck %s --check-prefix=CHECK
 
-# CHECK32:      --- !XCOFF
-# CHECK32-NEXT: FileHeader:
-# CHECK32-NEXT:   MagicNumber:     0x1DF
-# CHECK32-NEXT:   NumberOfSections: 0
-# CHECK32-NEXT:   CreationTime:    0
-# CHECK32-NEXT:   OffsetToSymbolTable: 0x14
-# CHECK32-NEXT:   EntriesInSymbolTable: 10
-# CHECK32-NEXT:   AuxiliaryHeaderSize: 0
-# CHECK32-NEXT:   Flags:           0x0
-# CHECK32-NEXT: Symbols:
-# CHECK32:       - Name:            .fcn1
-# CHECK32-NEXT:    Value:           0x0
-# CHECK32-NEXT:    Section:         N_UNDEF
-# CHECK32-NEXT:    Type:            0x0
-# CHECK32-NEXT:    StorageClass:    C_EXT
-# CHECK32-NEXT:    NumberOfAuxEntries: 1
-# CHECK32-NEXT:    AuxEntries:
-# CHECK32-NEXT:      - Type:            AUX_CSECT
-# CHECK32-NEXT:        ParameterHashIndex: 0
-# CHECK32-NEXT:        TypeChkSectNum:  0
-# CHECK32-NEXT:        SymbolType:      XTY_SD
-# CHECK32-NEXT:        SymbolAlignment: 4
-# CHECK32-NEXT:        StorageMappingClass: XMC_PR
-# CHECK32:       - Name:            .fcn2
-# CHECK32-NEXT:    Value:           0x0
-# CHECK32-NEXT:    Section:         N_UNDEF
-# CHECK32-NEXT:    Type:            0x0
-# CHECK32-NEXT:    StorageClass:    C_EXT
-# CHECK32-NEXT:    NumberOfAuxEntries: 1
-# CHECK32-NEXT:    AuxEntries:
-# CHECK32-NEXT:      - Type:            AUX_CSECT
-# CHECK32-NEXT:        ParameterHashIndex: 0
-# CHECK32-NEXT:        TypeChkSectNum:  0
-# CHECK32-NEXT:        SymbolType:      XTY_SD
-# CHECK32-NEXT:        SymbolAlignment: 2
-# CHECK32-NEXT:        StorageMappingClass: XMC_PR
-# CHECK32:       - Name:            .fcn3
-# CHECK32-NEXT:    Value:           0x0
-# CHECK32-NEXT:    Section:         N_UNDEF
-# CHECK32-NEXT:    Type:            0x0
-# CHECK32-NEXT:    StorageClass:    C_EXT
-# CHECK32-NEXT:    NumberOfAuxEntries: 1
-# CHECK32-NEXT:    AuxEntries:
-# CHECK32-NEXT:      - Type:            AUX_CSECT
-# CHECK32-NEXT:        ParameterHashIndex: 0
-# CHECK32-NEXT:        TypeChkSectNum:  0
-# CHECK32-NEXT:        SymbolType:      XTY_SD
-# CHECK32-NEXT:        SymbolAlignment: 0
-# CHECK32-NEXT:        StorageMappingClass: XMC_PR
-# CHECK32:       - Name:            .fcn4
-# CHECK32-NEXT:    Value:           0x0
-# CHECK32-NEXT:    Section:         N_UNDEF
-# CHECK32-NEXT:    Type:            0x0
-# CHECK32-NEXT:    StorageClass:    C_EXT
-# CHECK32-NEXT:    NumberOfAuxEntries: 1
-# CHECK32-NEXT:    AuxEntries:
-# CHECK32-NEXT:      - Type:            AUX_CSECT
-# CHECK32-NEXT:        ParameterHashIndex: 0
-# CHECK32-NEXT:        TypeChkSectNum:  0
-# CHECK32-NEXT:        SymbolType:      XTY_ER
-# CHECK32-NEXT:        SymbolAlignment: 5
-# CHECK32-NEXT:        StorageMappingClass: XMC_PR
+# CHECK:        --- !XCOFF
+# CHECK-NEXT: FileHeader:
+# CHECK-NEXT:   MagicNumber:
+# CHECK:      Symbols:
+# CHECK:       - Name:            .fcn1
+# CHECK:         NumberOfAuxEntries: 1
+# CHECK-NEXT:    AuxEntries:
+# CHECK-NEXT:      - Type:            AUX_CSECT
+# CHECK:             SymbolType:      XTY_SD
+# CHECK-NEXT:        SymbolAlignment: 4
+# CHECK:       - Name:            .fcn2
+# CHECK:         NumberOfAuxEntries: 1
+# CHECK-NEXT:    AuxEntries:
+# CHECK-NEXT:      - Type:            AUX_CSECT
+# CHECK:             SymbolType:      XTY_SD
+# CHECK-NEXT:        SymbolAlignment: 2
+# CHECK:       - Name:            .fcn3
+# CHECK:         NumberOfAuxEntries: 1
+# CHECK-NEXT:    AuxEntries:
+# CHECK-NEXT:      - Type:            AUX_CSECT
+# CHECK:             SymbolType:      XTY_SD
+# CHECK-NEXT:        SymbolAlignment: 0
+# CHECK:       - Name:            .fcn4
+# CHECK:         NumberOfAuxEntries: 1
+# CHECK-NEXT:    AuxEntries:
+# CHECK-NEXT:      - Type:            AUX_CSECT
+# CHECK:             SymbolType:      XTY_SD
+# CHECK-NEXT:        SymbolAlignment: 31
 
 --- !XCOFF
 FileHeader:
-  MagicNumber: 0x1DF
+  MagicNumber: [[MAGIC]]
 Symbols:
-  - StorageClass:    C_FILE
+  - StorageClass: C_FILE
     AuxEntries:
-      - Type:             AUX_FILE
+      - Type: AUX_FILE
         FileNameOrString: FileName
         FileStringType:   XFT_CD
-  - StorageClass:    C_EXT
-    Name:               .fcn1
+  - StorageClass: C_EXT
+    Name: .fcn1
     AuxEntries:
-      - Type:               AUX_CSECT
+      - Type: AUX_CSECT
         SymbolAlignmentAndType: 17
         SymbolAlignment: 4
-        SectionOrLength:    4
-  - StorageClass:    C_EXT
-    Name:               .fcn2
+        [[SectionOrLength]]: 4
+  - StorageClass: C_EXT
+    Name: .fcn2
     AuxEntries:
-      - Type:               AUX_CSECT
+      - Type: AUX_CSECT
         SymbolAlignmentAndType: 18
         SymbolType: XTY_SD
-        SectionOrLength:    4
+        [[SectionOrLength]]: 4
   - StorageClass:    C_EXT
-    Name:               .fcn3
+    Name: .fcn3
     AuxEntries:
-      - Type:               AUX_CSECT
+      - Type: AUX_CSECT
         SymbolType: XTY_SD
-        SectionOrLength:    4
+        [[SectionOrLength]]: 4
   - StorageClass:    C_EXT
-    Name:               .fcn4
+    Name: .fcn4
     AuxEntries:
-      - Type:               AUX_CSECT
-        SymbolAlignment: 5
-        SectionOrLength:    4
+      - Type: AUX_CSECT
+        SymbolType: XTY_SD
+        SymbolAlignment: 31
+        [[SectionOrLength]]: 4
 
-# RUN: yaml2obj %s --docnum=2 -o %t64
-# RUN: obj2yaml %t64 | FileCheck %s --check-prefix=CHECK64
-#
-# CHECK64:      --- !XCOFF
-# CHECK64-NEXT: FileHeader:
-# CHECK64-NEXT:   MagicNumber:     0x1F7
-# CHECK64-NEXT:   NumberOfSections: 0
-# CHECK64-NEXT:   CreationTime:    0
-# CHECK64-NEXT:   OffsetToSymbolTable: 0x18
-# CHECK64-NEXT:   EntriesInSymbolTable: 10
-# CHECK64-NEXT:   AuxiliaryHeaderSize: 0
-# CHECK64-NEXT:   Flags:           0x0
-# CHECK64-NEXT: Symbols:
-# CHECK64:        - Name:            .fcn1
-# CHECK64-NEXT:     Value:           0x0
-# CHECK64-NEXT:     Section:         N_UNDEF
-# CHECK64-NEXT:     Type:            0x0
-# CHECK64-NEXT:     StorageClass:    C_EXT
-# CHECK64-NEXT:     NumberOfAuxEntries: 1
-# CHECK64-NEXT:     AuxEntries:
-# CHECK64-NEXT:       - Type:            AUX_CSECT
-# CHECK64-NEXT:         ParameterHashIndex: 0
-# CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolType:      XTY_SD
-# CHECK64-NEXT:         SymbolAlignment: 4
-# CHECK64-NEXT:         StorageMappingClass: XMC_PR
-# CHECK64-NEXT:         SectionOrLengthLo: 4
-# CHECK64:        - Name:            .fcn2
-# CHECK64-NEXT:     Value:           0x0
-# CHECK64-NEXT:     Section:         N_UNDEF
-# CHECK64-NEXT:     Type:            0x0
-# CHECK64-NEXT:     StorageClass:    C_EXT
-# CHECK64-NEXT:     NumberOfAuxEntries: 1
-# CHECK64-NEXT:     AuxEntries:
-# CHECK64-NEXT:       - Type:            AUX_CSECT
-# CHECK64-NEXT:         ParameterHashIndex: 0
-# CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolType:      XTY_SD
-# CHECK64-NEXT:         SymbolAlignment: 2
-# CHECK64-NEXT:         StorageMappingClass: XMC_PR
-# CHECK64-NEXT:         SectionOrLengthLo: 4
-# CHECK64:        - Name:            .fcn3
-# CHECK64-NEXT:     Value:           0x0
-# CHECK64-NEXT:     Section:         N_UNDEF
-# CHECK64-NEXT:     Type:            0x0
-# CHECK64-NEXT:     StorageClass:    C_EXT
-# CHECK64-NEXT:     NumberOfAuxEntries: 1
-# CHECK64-NEXT:     AuxEntries:
-# CHECK64-NEXT:       - Type:            AUX_CSECT
-# CHECK64-NEXT:         ParameterHashIndex: 0
-# CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolType:      XTY_SD
-# CHECK64-NEXT:         SymbolAlignment: 0
-# CHECK64-NEXT:         StorageMappingClass: XMC_PR
-# CHECK64-NEXT:         SectionOrLengthLo: 4
-# CHECK64:        - Name:            .fcn4
-# CHECK64-NEXT:     Value:           0x0
-# CHECK64-NEXT:     Section:         N_UNDEF
-# CHECK64-NEXT:     Type:            0x0
-# CHECK64-NEXT:     StorageClass:    C_EXT
-# CHECK64-NEXT:     NumberOfAuxEntries: 1
-# CHECK64-NEXT:     AuxEntries:
-# CHECK64-NEXT:       - Type:            AUX_CSECT
-# CHECK64-NEXT:         ParameterHashIndex: 0
-# CHECK64-NEXT:         TypeChkSectNum:  0
-# CHECK64-NEXT:         SymbolType:      XTY_ER
-# CHECK64-NEXT:         SymbolAlignment: 5
-# CHECK64-NEXT:         StorageMappingClass: XMC_PR
-# CHECK64-NEXT:         SectionOrLengthLo: 4
 
+## Ensure that SymbolAlignment is in range.
+# RUN: not yaml2obj %s --docnum=2 -o %t 2>&1 | FileCheck %s --check-prefix=ERROR1
+# ERROR1: Symbol alignment must be less than 32
 --- !XCOFF
 FileHeader:
   MagicNumber:     0x1F7
@@ -185,25 +90,6 @@ Symbols:
     Name:               .fcn1
     AuxEntries:
       - Type:               AUX_CSECT
-        SymbolAlignmentAndType: 17
-        SymbolAlignment: 4
-        SectionOrLengthLo:    4
-  - StorageClass:    C_EXT
-    Name:               .fcn2
-    AuxEntries:
-      - Type:               AUX_CSECT
-        SymbolAlignmentAndType: 18
         SymbolType: XTY_SD
-        SectionOrLengthLo:    4
-  - StorageClass:    C_EXT
-    Name:               .fcn3
-    AuxEntries:
-      - Type:               AUX_CSECT
-        SymbolType: XTY_SD
-        SectionOrLengthLo:    4
-  - StorageClass:    C_EXT
-    Name:               .fcn4
-    AuxEntries:
-      - Type:               AUX_CSECT
-        SymbolAlignment: 5
+        SymbolAlignment: 32
         SectionOrLengthLo:    4

>From 77c3cda7de3cec52bc470bf38fcc32697411474d Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Tue, 16 Jan 2024 12:11:46 -0500
Subject: [PATCH 4/4] Disallow SymbolType or SymbolAlignment if
 SymbolAlignmentAndType is used.

---
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp          | 35 +++++---
 .../tools/obj2yaml/XCOFF/aux-aligntype.yaml   | 85 ++++++++++++++-----
 2 files changed, 86 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index cfda91ba7d3159c..56b1950e756ce68 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -526,22 +526,29 @@ bool XCOFFWriter::writeRelocations() {
 }
 
 bool XCOFFWriter::writeAuxSymbol(const XCOFFYAML::CsectAuxEnt &AuxSym) {
-  uint8_t SymAlignAndType = AuxSym.SymbolAlignmentAndType.value_or(0);
-  if (AuxSym.SymbolType)
-    SymAlignAndType = (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolTypeMask) |
-                      *AuxSym.SymbolType;
-  if (AuxSym.SymbolAlignment) {
-    const uint8_t ShiftedSymbolAlignmentMask =
-        XCOFFCsectAuxRef::SymbolAlignmentMask >>
-        XCOFFCsectAuxRef::SymbolAlignmentBitOffset;
-
-    if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {
-      ErrHandler("Symbol alignment must be less than " +
-                 Twine(1 + ShiftedSymbolAlignmentMask));
+  uint8_t SymAlignAndType = 0;
+  if (AuxSym.SymbolAlignmentAndType) {
+    if (AuxSym.SymbolType || AuxSym.SymbolAlignment) {
+      ErrHandler("cannot specify SymbolType or SymbolAlignment if "
+                 "SymbolAlignmentAndType is specified");
       return false;
     }
-    SymAlignAndType =
-        (SymAlignAndType & ~XCOFFCsectAuxRef::SymbolAlignmentMask) |
+    SymAlignAndType = *AuxSym.SymbolAlignmentAndType;
+  } else {
+    if (AuxSym.SymbolType)
+      SymAlignAndType = *AuxSym.SymbolType;
+    if (AuxSym.SymbolAlignment) {
+      const uint8_t ShiftedSymbolAlignmentMask =
+          XCOFFCsectAuxRef::SymbolAlignmentMask >>
+          XCOFFCsectAuxRef::SymbolAlignmentBitOffset;
+
+      if (*AuxSym.SymbolAlignment & ~ShiftedSymbolAlignmentMask) {
+        ErrHandler("symbol alignment must be less than " +
+                   Twine(1 + ShiftedSymbolAlignmentMask));
+        return false;
+      }
+    }
+    SymAlignAndType |=
         (*AuxSym.SymbolAlignment << XCOFFCsectAuxRef::SymbolAlignmentBitOffset);
   }
   if (Is64Bit) {
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
index 4a9d99ef012f475..5aa2d5537d66262 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aux-aligntype.yaml
@@ -1,6 +1,6 @@
-## Check that obj2yaml can parse SymbolAlignmentAndType, SymbolAlignment, and SymbolType.
-## If either SymbolAlignment or SymbolType are specified along with SymbolAligmentAndType,
-## their values override the corresponding portions of SymbolAligmentAndType.
+## Check that obj2yaml can parse SymbolAlignmentAndType, SymbolAlignment,
+## and SymbolType.  If either SymbolAlignment or SymbolType are specified
+## along with SymbolAligmentAndType, report an error.
 
 # RUN: yaml2obj %s --docnum=1 -DMAGIC=0x01DF -DSectionOrLength=SectionOrLength -o %t32
 # RUN: obj2yaml %t32 | FileCheck %s --check-prefix=CHECK
@@ -15,7 +15,7 @@
 # CHECK:         NumberOfAuxEntries: 1
 # CHECK-NEXT:    AuxEntries:
 # CHECK-NEXT:      - Type:            AUX_CSECT
-# CHECK:             SymbolType:      XTY_SD
+# CHECK:             SymbolType:      XTY_ER
 # CHECK-NEXT:        SymbolAlignment: 4
 # CHECK:       - Name:            .fcn2
 # CHECK:         NumberOfAuxEntries: 1
@@ -29,12 +29,6 @@
 # CHECK-NEXT:      - Type:            AUX_CSECT
 # CHECK:             SymbolType:      XTY_SD
 # CHECK-NEXT:        SymbolAlignment: 0
-# CHECK:       - Name:            .fcn4
-# CHECK:         NumberOfAuxEntries: 1
-# CHECK-NEXT:    AuxEntries:
-# CHECK-NEXT:      - Type:            AUX_CSECT
-# CHECK:             SymbolType:      XTY_SD
-# CHECK-NEXT:        SymbolAlignment: 31
 
 --- !XCOFF
 FileHeader:
@@ -49,14 +43,13 @@ Symbols:
     Name: .fcn1
     AuxEntries:
       - Type: AUX_CSECT
-        SymbolAlignmentAndType: 17
         SymbolAlignment: 4
         [[SectionOrLength]]: 4
   - StorageClass: C_EXT
     Name: .fcn2
     AuxEntries:
       - Type: AUX_CSECT
-        SymbolAlignmentAndType: 18
+        SymbolAlignment: 2
         SymbolType: XTY_SD
         [[SectionOrLength]]: 4
   - StorageClass:    C_EXT
@@ -65,14 +58,6 @@ Symbols:
       - Type: AUX_CSECT
         SymbolType: XTY_SD
         [[SectionOrLength]]: 4
-  - StorageClass:    C_EXT
-    Name: .fcn4
-    AuxEntries:
-      - Type: AUX_CSECT
-        SymbolType: XTY_SD
-        SymbolAlignment: 31
-        [[SectionOrLength]]: 4
-
 
 ## Ensure that SymbolAlignment is in range.
 # RUN: not yaml2obj %s --docnum=2 -o %t 2>&1 | FileCheck %s --check-prefix=ERROR1
@@ -93,3 +78,63 @@ Symbols:
         SymbolType: XTY_SD
         SymbolAlignment: 32
         SectionOrLengthLo:    4
+
+## Ensure that neither SymbolAlignment nor SymbolType can be specified if
+## SymbolAlignmentAndType is specified.
+# RUN: not yaml2obj %s --docnum=3 -o %t 2>&1 | FileCheck %s --check-prefix=ERROR2
+# ERROR2: cannot specify SymbolType or SymbolAlignment if SymbolAlignmentAndType is specified
+--- !XCOFF
+FileHeader:
+  MagicNumber: 0x1DF
+Symbols:
+  - StorageClass: C_FILE
+    AuxEntries:
+      - Type: AUX_FILE
+        FileNameOrString: FileName
+        FileStringType:   XFT_CD
+  - StorageClass: C_EXT
+    Name: .fcn1
+    AuxEntries:
+      - Type: AUX_CSECT
+        SymbolAlignmentAndType: 17
+        SymbolAlignment: 4
+        SectionOrLength: 4
+
+# RUN: not yaml2obj %s --docnum=4 -o %t 2>&1 | FileCheck %s --check-prefix=ERROR2
+--- !XCOFF
+FileHeader:
+  MagicNumber: 0x1DF
+Symbols:
+  - StorageClass: C_FILE
+    AuxEntries:
+      - Type: AUX_FILE
+        FileNameOrString: FileName
+        FileStringType:   XFT_CD
+  - StorageClass: C_EXT
+    Name: .fcn1
+    AuxEntries:
+      - Type: AUX_CSECT
+        SymbolAlignmentAndType: 17
+        SymbolAlignment: 4
+        SymbolType: XTY_CM
+        SectionOrLength: 4
+
+# RUN: not yaml2obj %s --docnum=5 -o %t 2>&1 | FileCheck %s --check-prefix=ERROR2
+--- !XCOFF
+FileHeader:
+  MagicNumber: 0x1F7
+Symbols:
+  - StorageClass: C_FILE
+    AuxEntries:
+      - Type: AUX_FILE
+        FileNameOrString: FileName
+        FileStringType:   XFT_CD
+  - StorageClass: C_EXT
+  - StorageClass: C_EXT
+    Name: .fcn2
+    AuxEntries:
+      - Type: AUX_CSECT
+        SymbolAlignmentAndType: 18
+        SymbolType: XTY_SD
+        SectionOrLengthLo: 4
+



More information about the llvm-commits mailing list