[llvm] [yaml2obj][XOFF] Update yaml2obj for XCOFF to create valid XCOFF files in more cases. (PR #77620)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 7 14:39:48 PST 2024


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

>From 97f907f3a155d3b247d4035bac3e732e5b71b90d Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Wed, 10 Jan 2024 11:36:41 -0500
Subject: [PATCH 1/5] Update yaml for XCOFF to create valid XCOFF files in more
 cases.

yaml2obj creates invalid object files even when the input was
created by obj2yaml using a valid object file. On the other hand,
yaml2obj is used to intentionally create invalid object files for
testing purposes.

This update balances using specified input values when provided and
computing file offsets and sizes if necessary.
---
 llvm/include/llvm/ObjectYAML/XCOFFYAML.h      |   2 +-
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp          | 201 ++++++++++--------
 .../llvm-objcopy/XCOFF/invalid-read.test      |   6 +-
 .../XCOFF/disassemble-traceback-table.test    |   2 +-
 .../llvm-objdump/XCOFF/section-headers.test   |   2 +-
 .../tools/llvm-readobj/XCOFF/file-header.test |   3 +-
 .../tools/llvm-readobj/XCOFF/sections.test    |  20 +-
 llvm/test/tools/obj2yaml/XCOFF/aix.yaml       |   4 +-
 .../tools/obj2yaml/XCOFF/invalid-section.yaml |   3 +-
 .../yaml2obj/XCOFF/aux-hdr-defaults.yaml      |  24 +--
 llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml |   4 +-
 11 files changed, 150 insertions(+), 121 deletions(-)

diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
index f1e821fe5fa369..e4b6a5d2f8de17 100644
--- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
@@ -26,7 +26,7 @@ struct FileHeader {
   int32_t TimeStamp;
   llvm::yaml::Hex64 SymbolTableOffset;
   int32_t NumberOfSymTableEntries;
-  uint16_t AuxHeaderSize;
+  std::optional<uint16_t> AuxHeaderSize;
   llvm::yaml::Hex16 Flags;
 };
 
diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index ccf768c06aebfe..7f78aaf749dbcc 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -43,14 +43,14 @@ class XCOFFWriter {
   bool nameShouldBeInStringTable(StringRef SymbolName);
   bool initFileHeader(uint64_t CurrentOffset);
   void initAuxFileHeader();
-  bool initSectionHeader(uint64_t &CurrentOffset);
+  bool initSectionHeaders(uint64_t &CurrentOffset);
   bool initRelocations(uint64_t &CurrentOffset);
   bool initStringTable();
   bool assignAddressesAndIndices();
 
   void writeFileHeader();
   void writeAuxFileHeader();
-  void writeSectionHeader();
+  void writeSectionHeaders();
   bool writeSectionData();
   bool writeRelocations();
   bool writeSymbols();
@@ -98,11 +98,27 @@ bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {
 bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
   for (XCOFFYAML::Section &InitSection : InitSections) {
     if (!InitSection.Relocations.empty()) {
-      InitSection.NumberOfRelocations = InitSection.Relocations.size();
-      InitSection.FileOffsetToRelocations = CurrentOffset;
       uint64_t RelSize = Is64Bit ? XCOFF::RelocationSerializationSize64
                                  : XCOFF::RelocationSerializationSize32;
-      CurrentOffset += InitSection.NumberOfRelocations * RelSize;
+      const uint64_t UsedSize = RelSize * InitSection.Relocations.size();
+
+      // If NumberOfRelocations was specified, we use it, even if it's
+      // not consistent with the number of provided relocations
+      if (!InitSection.NumberOfRelocations)
+        InitSection.NumberOfRelocations = InitSection.Relocations.size();
+
+      // If the YAML file specified an offset to relocations, we use it.
+      if (InitSection.FileOffsetToRelocations) {
+        if (CurrentOffset > InitSection.FileOffsetToRelocations) {
+          ErrHandler("Specified FileOffsetToRelocations will overwrite"
+                     "existing data");
+          return false;
+        }
+        CurrentOffset = InitSection.FileOffsetToRelocations;
+      }
+      else
+        InitSection.FileOffsetToRelocations = CurrentOffset;
+      CurrentOffset += UsedSize;
       if (CurrentOffset > MaxRawDataSize) {
         ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
                    "exceeded when writing relocation data");
@@ -113,15 +129,10 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
   return true;
 }
 
-bool XCOFFWriter::initSectionHeader(uint64_t &CurrentOffset) {
-  uint64_t CurrentSecAddr = 0;
+bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
+  uint64_t CurrentDataAddr = 0;
+  uint64_t CurrentTDataAddr = 0;
   for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
-    if (CurrentOffset > MaxRawDataSize) {
-      ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
-                 "exceeded when writing section data");
-      return false;
-    }
-
     // Assign indices for sections.
     if (InitSections[I].SectionName.size() &&
         !SectionIndexMap[InitSections[I].SectionName]) {
@@ -134,23 +145,46 @@ bool XCOFFWriter::initSectionHeader(uint64_t &CurrentOffset) {
       }
     }
 
-    // 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;
+    if (!InitSections[I].Size)
+      InitSections[I].Size = InitSections[I].SectionData.binary_size();
+
+    // We cannot compute section addresses in general. We only enforce
+    // the rule .data and .bss are consecutive, as are .tdata and .tbss.
+    switch(InitSections[I].Flags) {
+      case XCOFF::STYP_DATA:
+        CurrentDataAddr = InitSections[I].Address + InitSections[I].Size;
+        break;
+      case XCOFF::STYP_BSS:
+        if (!InitSections[I].Address)
+          InitSections[I].Address = CurrentDataAddr;
+        break;
+      case XCOFF::STYP_TDATA:
+        CurrentTDataAddr = InitSections[I].Address + InitSections[I].Size;
+        break;
+      case XCOFF::STYP_TBSS:
+        if (!InitSections[I].Address)
+          InitSections[I].Address = CurrentTDataAddr;
+        break;
+    }
 
-    // Calculate the FileOffsetToData and data size for sections.
     if (InitSections[I].SectionData.binary_size()) {
-      InitSections[I].FileOffsetToData = CurrentOffset;
+      if (InitSections[I].FileOffsetToData) {
+        // Use the providedFileOffsetToData.
+        if (CurrentOffset > InitSections[I].FileOffsetToData) {
+          ErrHandler("Specified FileOffsetToData will overwrite existing data");
+          return false;
+        }
+        CurrentOffset = InitSections[I].FileOffsetToData;
+      } else {
+         CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
+         InitSections[I].FileOffsetToData = CurrentOffset;
+      }
       CurrentOffset += InitSections[I].SectionData.binary_size();
-      // Ensure the offset is aligned to DefaultSectionAlign.
-      CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
-      InitSections[I].Size = CurrentOffset - InitSections[I].FileOffsetToData;
-      CurrentSecAddr += InitSections[I].Size;
+      if (CurrentOffset > MaxRawDataSize) {
+        ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
+                   "exceeded when writing section data");
+        return false;
+      }
     }
   }
   return initRelocations(CurrentOffset);
@@ -254,6 +288,13 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
 
   // Calculate SymbolTableOffset for the file header.
   if (InitFileHdr.NumberOfSymTableEntries) {
+    if (Obj.Header.SymbolTableOffset) {
+      if (CurrentOffset > Obj.Header.SymbolTableOffset) {
+        ErrHandler("symbol table offset overlaps existing data");
+        return false;
+      }
+      CurrentOffset = Obj.Header.SymbolTableOffset;
+    }
     InitFileHdr.SymbolTableOffset = CurrentOffset;
     CurrentOffset +=
         InitFileHdr.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;
@@ -268,7 +309,8 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
 }
 
 void XCOFFWriter::initAuxFileHeader() {
-  InitAuxFileHdr = *Obj.AuxHeader;
+  if (Obj.AuxHeader)
+    InitAuxFileHdr = *Obj.AuxHeader;
   // In general, an object file might contain multiple sections of a given type,
   // but in a loadable module, there must be exactly one .text, .data, .bss, and
   // .loader section. A loadable object might also have one .tdata section and
@@ -320,30 +362,31 @@ void XCOFFWriter::initAuxFileHeader() {
 }
 
 bool XCOFFWriter::assignAddressesAndIndices() {
-  uint64_t FileHdrSize =
+  const uint64_t FileHdrSize =
       Is64Bit ? XCOFF::FileHeaderSize64 : XCOFF::FileHeaderSize32;
-  uint64_t AuxFileHdrSize = 0;
-  if (Obj.AuxHeader)
-    AuxFileHdrSize = Obj.Header.AuxHeaderSize
-                         ? Obj.Header.AuxHeaderSize
-                         : (Is64Bit ? XCOFF::AuxFileHeaderSize64
-                                    : XCOFF::AuxFileHeaderSize32);
-  uint64_t SecHdrSize =
+
+  // If AuxHeaderSize is specified in the YAML file, we construct
+  // an auxiliary header.
+  const uint64_t AuxFileHdrSize =
+      Obj.Header.AuxHeaderSize ? *Obj.Header.AuxHeaderSize :
+      !Obj.AuxHeader ? 0 :
+      (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
+  const uint64_t SecHdrSize =
       Is64Bit ? XCOFF::SectionHeaderSize64 : XCOFF::SectionHeaderSize32;
   uint64_t CurrentOffset =
       FileHdrSize + AuxFileHdrSize + InitSections.size() * SecHdrSize;
 
   // Calculate section header info.
-  if (!initSectionHeader(CurrentOffset))
+  if (!initSectionHeaders(CurrentOffset))
     return false;
-  InitFileHdr.AuxHeaderSize = AuxFileHdrSize;
 
   // Calculate file header info.
   if (!initFileHeader(CurrentOffset))
     return false;
+  InitFileHdr.AuxHeaderSize = AuxFileHdrSize;
 
   // Initialize the auxiliary file header.
-  if (Obj.AuxHeader)
+  if (AuxFileHdrSize)
     initAuxFileHeader();
 
   // Initialize the string table.
@@ -356,22 +399,18 @@ void XCOFFWriter::writeFileHeader() {
                                                 : InitFileHdr.NumberOfSections);
   W.write<int32_t>(Obj.Header.TimeStamp);
   if (Is64Bit) {
-    W.write<uint64_t>(Obj.Header.SymbolTableOffset
-                          ? Obj.Header.SymbolTableOffset
-                          : InitFileHdr.SymbolTableOffset);
-    W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
+    W.write<uint64_t>(InitFileHdr.SymbolTableOffset);
+    W.write<uint16_t>(*InitFileHdr.AuxHeaderSize);
     W.write<uint16_t>(Obj.Header.Flags);
     W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
                          ? Obj.Header.NumberOfSymTableEntries
                          : InitFileHdr.NumberOfSymTableEntries);
   } else {
-    W.write<uint32_t>(Obj.Header.SymbolTableOffset
-                          ? Obj.Header.SymbolTableOffset
-                          : InitFileHdr.SymbolTableOffset);
+    W.write<uint32_t>(InitFileHdr.SymbolTableOffset);
     W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
                          ? Obj.Header.NumberOfSymTableEntries
                          : InitFileHdr.NumberOfSymTableEntries);
-    W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
+    W.write<uint16_t>(*InitFileHdr.AuxHeaderSize);
     W.write<uint16_t>(Obj.Header.Flags);
   }
 }
@@ -391,6 +430,9 @@ void XCOFFWriter::writeAuxFileHeader() {
     W.write<uint32_t>(InitAuxFileHdr.EntryPointAddr.value_or(yaml::Hex64(0)));
     W.write<uint32_t>(InitAuxFileHdr.TextStartAddr.value_or(yaml::Hex64(0)));
     W.write<uint32_t>(InitAuxFileHdr.DataStartAddr.value_or(yaml::Hex64(0)));
+    // A short 32-bit auxiliary header ends here.
+    if (*InitFileHdr.AuxHeaderSize == XCOFF::AuxFileHeaderSizeShort)
+      return;
     W.write<uint32_t>(InitAuxFileHdr.TOCAnchorAddr.value_or(yaml::Hex64(0)));
   }
   W.write<uint16_t>(InitAuxFileHdr.SecNumOfEntryPoint.value_or(0));
@@ -432,50 +474,39 @@ void XCOFFWriter::writeAuxFileHeader() {
     W.write<uint16_t>(
         InitAuxFileHdr.Flag.value_or(yaml::Hex16(XCOFF::SHR_SYMTAB)));
     if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize64)
-      W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize64);
-  } else if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize32) {
-    W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize32);
+      W.OS.write_zeros(*InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize64);
+  } else {
+    if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize32)
+      W.OS.write_zeros(*InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize32);
   }
 }
 
-void XCOFFWriter::writeSectionHeader() {
+void XCOFFWriter::writeSectionHeaders() {
   for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
-    XCOFFYAML::Section YamlSec = Obj.Sections[I];
     XCOFFYAML::Section DerivedSec = InitSections[I];
-    writeName(YamlSec.SectionName, W);
-    // Virtual address is the same as physical address.
-    uint64_t SectionAddress =
-        YamlSec.Address ? YamlSec.Address : DerivedSec.Address;
+    writeName(DerivedSec.SectionName, W);
     if (Is64Bit) {
-      W.write<uint64_t>(SectionAddress); // Physical address
-      W.write<uint64_t>(SectionAddress); // Virtual address
-      W.write<uint64_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
-      W.write<uint64_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
-                                                 : DerivedSec.FileOffsetToData);
-      W.write<uint64_t>(YamlSec.FileOffsetToRelocations
-                            ? YamlSec.FileOffsetToRelocations
-                            : DerivedSec.FileOffsetToRelocations);
-      W.write<uint64_t>(YamlSec.FileOffsetToLineNumbers);
-      W.write<uint32_t>(YamlSec.NumberOfRelocations
-                            ? YamlSec.NumberOfRelocations
-                            : DerivedSec.NumberOfRelocations);
-      W.write<uint32_t>(YamlSec.NumberOfLineNumbers);
+      // Virtual address is the same as physical address.
+      W.write<uint64_t>(DerivedSec.Address); // Physical address
+      W.write<uint64_t>(DerivedSec.Address); // Virtual address
+      W.write<uint64_t>(DerivedSec.Size);
+      W.write<uint64_t>(DerivedSec.FileOffsetToData);
+      W.write<uint64_t>(DerivedSec.FileOffsetToRelocations);
+      W.write<uint64_t>(DerivedSec.FileOffsetToLineNumbers);
+      W.write<uint32_t>(DerivedSec.NumberOfRelocations);
+      W.write<uint32_t>(DerivedSec.NumberOfLineNumbers);
       W.write<int32_t>(YamlSec.Flags);
       W.OS.write_zeros(4);
     } else {
-      W.write<uint32_t>(SectionAddress); // Physical address
-      W.write<uint32_t>(SectionAddress); // Virtual address
-      W.write<uint32_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
-      W.write<uint32_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
-                                                 : DerivedSec.FileOffsetToData);
-      W.write<uint32_t>(YamlSec.FileOffsetToRelocations
-                            ? YamlSec.FileOffsetToRelocations
-                            : DerivedSec.FileOffsetToRelocations);
-      W.write<uint32_t>(YamlSec.FileOffsetToLineNumbers);
-      W.write<uint16_t>(YamlSec.NumberOfRelocations
-                            ? YamlSec.NumberOfRelocations
-                            : DerivedSec.NumberOfRelocations);
-      W.write<uint16_t>(YamlSec.NumberOfLineNumbers);
+      // Virtual address is the same as physical address.
+      W.write<uint32_t>(DerivedSec.Address); // Physical address
+      W.write<uint32_t>(DerivedSec.Address); // Virtual address
+      W.write<uint32_t>(DerivedSec.Size);
+      W.write<uint32_t>(DerivedSec.FileOffsetToData);
+      W.write<uint32_t>(DerivedSec.FileOffsetToRelocations);
+      W.write<uint32_t>(DerivedSec.FileOffsetToLineNumbers);
+      W.write<uint16_t>(DerivedSec.NumberOfRelocations);
+      W.write<uint16_t>(DerivedSec.NumberOfLineNumbers);
       W.write<int32_t>(YamlSec.Flags);
     }
   }
@@ -645,7 +676,7 @@ void XCOFFWriter::writeAuxSymbol(
 
 bool XCOFFWriter::writeSymbols() {
   int64_t PaddingSize =
-      (uint64_t)InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
+      InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
   if (PaddingSize < 0) {
     ErrHandler("redundant data was written before symbols");
     return false;
@@ -756,10 +787,10 @@ bool XCOFFWriter::writeXCOFF() {
     return false;
   StartOffset = W.OS.tell();
   writeFileHeader();
-  if (Obj.AuxHeader)
+  if (InitFileHdr.AuxHeaderSize.value_or(0))
     writeAuxFileHeader();
   if (!Obj.Sections.empty()) {
-    writeSectionHeader();
+    writeSectionHeaders();
     if (!writeSectionData())
       return false;
     if (!writeRelocations())
diff --git a/llvm/test/tools/llvm-objcopy/XCOFF/invalid-read.test b/llvm/test/tools/llvm-objcopy/XCOFF/invalid-read.test
index 1df63406a41361..96dcd72b672c24 100644
--- a/llvm/test/tools/llvm-objcopy/XCOFF/invalid-read.test
+++ b/llvm/test/tools/llvm-objcopy/XCOFF/invalid-read.test
@@ -5,7 +5,7 @@
 # RUN: yaml2obj %s --docnum=1 -o %t1
 # RUN: not llvm-objcopy %t1 %t1.out 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=ERROR1
 
-# ERROR1: error: '[[FILE]]': The end of the file was unexpectedly encountered: section data with offset 0x70 and size 0x4 goes past the end of the file
+# ERROR1: error: '[[FILE]]': The end of the file was unexpectedly encountered: section data with offset 0x70 and size 0x20 goes past the end of the file
 
 --- !XCOFF
 FileHeader:
@@ -13,6 +13,7 @@ FileHeader:
 Sections:
   - SectionData:      '00007400'
     FileOffsetToData: 0x70
+    Size: 0x20
 
 ## Failed to read relocations.
 # RUN: yaml2obj %s --docnum=2 -o %t2
@@ -35,12 +36,13 @@ Sections:
 # RUN: yaml2obj %s --docnum=3 -o %t3
 # RUN: not llvm-objcopy %t3 %t3.out 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=ERROR3
 
-# ERROR3: error: '[[FILE]]': The end of the file was unexpectedly encountered: symbol table with offset 0x15 and size 0x24 goes past the end of the file
+# ERROR3: error: '[[FILE]]': The end of the file was unexpectedly encountered: symbol table with offset 0x15 and size 0x36 goes past the end of the file
 
 --- !XCOFF
 FileHeader:
   MagicNumber:         0x01DF
   OffsetToSymbolTable: 0x15
+  EntriesInSymbolTable: 3
 Symbols:
   - Name:         foo
     AuxEntries:
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-traceback-table.test b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-traceback-table.test
index 91354f5a951e0d..96cac6b849fd52 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-traceback-table.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-traceback-table.test
@@ -112,4 +112,4 @@ Symbols:
 # CHECK-NEXT:      70: 00 00 00 00  
 # CHECK-NEXT:        ...
 # CHECK-NEXT:      7c: 00 12 34 00  
-# CHECK-NEXT:      80: 00 00 00 00  
+# CHECK-NEXT:      80: 00 00 00     
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/section-headers.test b/llvm/test/tools/llvm-objdump/XCOFF/section-headers.test
index e80d5f6a711b1a..1a110fb9642b85 100644
--- a/llvm/test/tools/llvm-objdump/XCOFF/section-headers.test
+++ b/llvm/test/tools/llvm-objdump/XCOFF/section-headers.test
@@ -10,7 +10,7 @@
 # CHECK-NEXT:   1 .data         00000004 00000000 DATA
 # CHECK-NEXT:   2 .bss          00000000 00000010 BSS
 # CHECK-NEXT:   3 .tdata        00000004 00000000 DATA
-# CHECK-NEXT:   4 .tbss         00000000 00000000 BSS
+# CHECK-NEXT:   4 .tbss         00000000 00000004 BSS
 # CHECK-NEXT:   5 .dwline       00000046 00000000 DEBUG
 # CHECK-NEXT:   6 .debug        00000046 00000000 DEBUG
 
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/file-header.test b/llvm/test/tools/llvm-readobj/XCOFF/file-header.test
index 8cbd84749fd48c..2407aef7264849 100644
--- a/llvm/test/tools/llvm-readobj/XCOFF/file-header.test
+++ b/llvm/test/tools/llvm-readobj/XCOFF/file-header.test
@@ -23,7 +23,6 @@ FileHeader:
   CreationTime:         [[CREATTIME=1]]
   EntriesInSymbolTable: [[SYMBOLCOUNT=1]]
   NumberOfSections:     1
-  OffsetToSymbolTable:  0x3C
   AuxiliaryHeaderSize:  0
   Flags:                0x12
 Sections:
@@ -42,7 +41,7 @@ Symbols:
 # FILEHEADER64-NEXT:  Magic: 0x1F7
 # FILEHEADER64-NEXT:  NumberOfSections: 1
 # FILEHEADER64-NEXT:  TimeStamp: None (0x0)
-# FILEHEADER64-NEXT:  SymbolTableOffset: 0x3C
+# FILEHEADER64-NEXT:  SymbolTableOffset: 0x60
 # FILEHEADER64-NEXT:  SymbolTableEntries: 1
 # FILEHEADER64-NEXT:  OptionalHeaderSize: 0x0
 # FILEHEADER64-NEXT:  Flags: 0x12
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/sections.test b/llvm/test/tools/llvm-readobj/XCOFF/sections.test
index be098939ce775a..36e85d6033652a 100644
--- a/llvm/test/tools/llvm-readobj/XCOFF/sections.test
+++ b/llvm/test/tools/llvm-readobj/XCOFF/sections.test
@@ -13,7 +13,7 @@
 # SEC32-NEXT:    Name: .text
 # SEC32-NEXT:    PhysicalAddress: 0x0
 # SEC32-NEXT:    VirtualAddress: 0x0
-# SEC32-NEXT:    Size: 0x4
+# SEC32-NEXT:    Size: 0x2
 # SEC32-NEXT:    RawDataOffset: 0x64
 # SEC32-NEXT:    RelocationPointer: 0x0
 # SEC32-NEXT:    LineNumberPointer: 0x0
@@ -24,11 +24,11 @@
 # SEC32-NEXT:  Section {
 # SEC32-NEXT:    Index: 2
 # SEC32-NEXT:    Name: .data
-# SEC32-NEXT:    PhysicalAddress: 0x4
-# SEC32-NEXT:    VirtualAddress: 0x4
-# SEC32-NEXT:    Size: 0x4
+# SEC32-NEXT:    PhysicalAddress: 0x0
+# SEC32-NEXT:    VirtualAddress: 0x0
+# SEC32-NEXT:    Size: 0x2
 # SEC32-NEXT:    RawDataOffset: 0x68
-# SEC32-NEXT:    RelocationPointer: 0x6C
+# SEC32-NEXT:    RelocationPointer: 0x6A
 # SEC32-NEXT:    LineNumberPointer: 0x0
 # SEC32-NEXT:    NumberOfRelocations: 1
 # SEC32-NEXT:    NumberOfLineNumbers: 0
@@ -65,7 +65,7 @@ Sections:
 # SEC64-NEXT:    Name: .text
 # SEC64-NEXT:    PhysicalAddress: 0x0
 # SEC64-NEXT:    VirtualAddress: 0x0
-# SEC64-NEXT:    Size: 0x4
+# SEC64-NEXT:    Size: 0x2
 # SEC64-NEXT:    RawDataOffset: 0xA8
 # SEC64-NEXT:    RelocationPointer: 0x0
 # SEC64-NEXT:    LineNumberPointer: 0x0
@@ -76,11 +76,11 @@ Sections:
 # SEC64-NEXT:  Section {
 # SEC64-NEXT:    Index: 2
 # SEC64-NEXT:    Name: .data
-# SEC64-NEXT:    PhysicalAddress: 0x4
-# SEC64-NEXT:    VirtualAddress: 0x4
-# SEC64-NEXT:    Size: 0x4
+# SEC64-NEXT:    PhysicalAddress: 0x0
+# SEC64-NEXT:    VirtualAddress: 0x0
+# SEC64-NEXT:    Size: 0x2
 # SEC64-NEXT:    RawDataOffset: 0xAC
-# SEC64-NEXT:    RelocationPointer: 0xB0
+# SEC64-NEXT:    RelocationPointer: 0xAE
 # SEC64-NEXT:    LineNumberPointer: 0x0
 # SEC64-NEXT:    NumberOfRelocations: 1
 # SEC64-NEXT:    NumberOfLineNumbers: 0
diff --git a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
index fbd5fa0629d10b..c5a11d25c369f8 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/aix.yaml
@@ -31,7 +31,7 @@
 # CHECK32-NEXT:         Info:            0xF
 # CHECK32-NEXT:         Type:            0x3
 # CHECK32-NEXT:   - Name:            .data
-# CHECK32-NEXT:     Address:         0x4
+# CHECK32-NEXT:     Address:         0x0
 # CHECK32-NEXT:     Size:            0x4
 # CHECK32-NEXT:     FileOffsetToData: 0x68
 # CHECK32-NEXT:     FileOffsetToRelocations: 0x76
@@ -103,7 +103,7 @@
 # CHECK64-NEXT:         Info:            0xF
 # CHECK64-NEXT:         Type:            0x3
 # CHECK64-NEXT:   - Name:            .data
-# CHECK64-NEXT:     Address:         0x4
+# CHECK64-NEXT:     Address:         0x0
 # CHECK64-NEXT:     Size:            0x4
 # CHECK64-NEXT:     FileOffsetToData: 0xAC
 # CHECK64-NEXT:     FileOffsetToRelocations: 0xBE
diff --git a/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml b/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
index 1e16c5f66baa38..0e16a47ae6a97a 100644
--- a/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
+++ b/llvm/test/tools/obj2yaml/XCOFF/invalid-section.yaml
@@ -5,7 +5,7 @@
 # RUN: yaml2obj %s --docnum=1 -o %t1
 # RUN: not obj2yaml %t1 2>&1 | FileCheck %s -DFILE=%t1 --check-prefix=ERROR1
 
-# ERROR1: The end of the file was unexpectedly encountered: section data with offset 0x70 and size 0x4 goes past the end of the file
+# ERROR1: The end of the file was unexpectedly encountered: section data with offset 0x70 and size 0x20 goes past the end of the file
 
 --- !XCOFF
 FileHeader:
@@ -13,6 +13,7 @@ FileHeader:
 Sections:
   - SectionData:      '00007400'
     FileOffsetToData: 0x70
+    Size: 0x20
 
 ## Error2: failed to get relocations.
 # RUN: yaml2obj %s --docnum=2 -o %t2
diff --git a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml
index f6d6193755ef22..a93123b231bad4 100644
--- a/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml
+++ b/llvm/test/tools/yaml2obj/XCOFF/aux-hdr-defaults.yaml
@@ -10,12 +10,12 @@
 # CASE1:      AuxiliaryHeader {
 # CASE1-NEXT:   Magic: 0x10B
 # CASE1-NEXT:   Version: 0x1
-# CASE1-NEXT:   Size of .text section: 0x8
-# CASE1-NEXT:   Size of .data section: 0x8
-# CASE1-NEXT:   Size of .bss section: 0x8
+# CASE1-NEXT:   Size of .text section: 0x5
+# CASE1-NEXT:   Size of .data section: 0x5
+# CASE1-NEXT:   Size of .bss section: 0x5
 # CASE1-NEXT:   Entry point address: 0x0
-# CASE1-NEXT:   .text section start address: 0x4
-# CASE1-NEXT:   .data section start address: 0x10
+# CASE1-NEXT:   .text section start address: 0x0
+# CASE1-NEXT:   .data section start address: 0x0
 # CASE1-NEXT:   TOC anchor address: 0x0
 # CASE1-NEXT:   Section number of entryPoint: 0
 # CASE1-NEXT:   Section number of .text: 2
@@ -79,16 +79,12 @@ Sections:
 # RUN: yaml2obj %s --docnum=1 -DMAGIC=0x1F7 -o %t2
 # RUN: llvm-readobj --auxiliary-header %t2 | FileCheck %s --check-prefix=CASE2
 
-## Case2: same as case1, except it is 64-bit.
-# RUN: yaml2obj %s --docnum=1 -DMAGIC=0x1F7 -o %t2
-# RUN: llvm-readobj --auxiliary-header %t2 | FileCheck %s --check-prefix=CASE2
-
 # CASE2:      AuxiliaryHeader {
 # CASE2-NEXT:   Magic: 0x10B
 # CASE2-NEXT:   Version: 0x1
 # CASE2-NEXT:   Reserved for debugger: 0x0
-# CASE2-NEXT:   .text section start address: 0x2
-# CASE2-NEXT:   .data section start address: 0xE
+# CASE2-NEXT:   .text section start address: 0x0
+# CASE2-NEXT:   .data section start address: 0x0
 # CASE2-NEXT:   TOC anchor address: 0x0
 # CASE2-NEXT:   Section number of entryPoint: 0
 # CASE2-NEXT:   Section number of .text: 2
@@ -106,9 +102,9 @@ Sections:
 # CASE2-NEXT:   Stack page size: 0x0
 # CASE2-NEXT:   Flag: 0x80
 # CASE2-NEXT:   Alignment of thread-local storage: 0x0
-# CASE2-NEXT:   Size of .text section: 0x8
-# CASE2-NEXT:   Size of .data section: 0x8
-# CASE2-NEXT:   Size of .bss section: 0x8
+# CASE2-NEXT:   Size of .text section: 0x5
+# CASE2-NEXT:   Size of .data section: 0x5
+# CASE2-NEXT:   Size of .bss section: 0x5
 # CASE2-NEXT:   Entry point address: 0x0
 # CASE2-NEXT:   Maximum stack size: 0x0
 # CASE2-NEXT:   Maximum data size: 0x0
diff --git a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml
index ed85bc639d0adc..8c3d77d842b029 100644
--- a/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml
+++ b/llvm/test/tools/yaml2obj/XCOFF/basic-doc.yaml
@@ -65,8 +65,8 @@ Symbols:
 # CHECK-NEXT:   Section {
 # CHECK-NEXT:     Index: 2
 # CHECK-NEXT:     Name: .data
-# CHECK-NEXT:     PhysicalAddress: 0x8
-# CHECK-NEXT:     VirtualAddress: 0x8
+# CHECK-NEXT:     PhysicalAddress: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x0
 # CHECK-NEXT:     Size: 0x8
 # CHECK-NEXT:     RawDataOffset: 0xE4
 # CHECK-NEXT:     RelocationPointer: 0xF0

>From 4f94966ce0d9054b07410a70e3ba34f602685fae Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Wed, 10 Jan 2024 12:00:35 -0500
Subject: [PATCH 2/5] Update formatting

---
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp | 44 ++++++++++++++--------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index 7f78aaf749dbcc..7a45dc8a67d4e1 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -115,8 +115,7 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
           return false;
         }
         CurrentOffset = InitSection.FileOffsetToRelocations;
-      }
-      else
+      } else
         InitSection.FileOffsetToRelocations = CurrentOffset;
       CurrentOffset += UsedSize;
       if (CurrentOffset > MaxRawDataSize) {
@@ -150,21 +149,21 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
 
     // We cannot compute section addresses in general. We only enforce
     // the rule .data and .bss are consecutive, as are .tdata and .tbss.
-    switch(InitSections[I].Flags) {
-      case XCOFF::STYP_DATA:
-        CurrentDataAddr = InitSections[I].Address + InitSections[I].Size;
-        break;
-      case XCOFF::STYP_BSS:
-        if (!InitSections[I].Address)
-          InitSections[I].Address = CurrentDataAddr;
-        break;
-      case XCOFF::STYP_TDATA:
-        CurrentTDataAddr = InitSections[I].Address + InitSections[I].Size;
-        break;
-      case XCOFF::STYP_TBSS:
-        if (!InitSections[I].Address)
-          InitSections[I].Address = CurrentTDataAddr;
-        break;
+    switch (InitSections[I].Flags) {
+    case XCOFF::STYP_DATA:
+      CurrentDataAddr = InitSections[I].Address + InitSections[I].Size;
+      break;
+    case XCOFF::STYP_BSS:
+      if (!InitSections[I].Address)
+        InitSections[I].Address = CurrentDataAddr;
+      break;
+    case XCOFF::STYP_TDATA:
+      CurrentTDataAddr = InitSections[I].Address + InitSections[I].Size;
+      break;
+    case XCOFF::STYP_TBSS:
+      if (!InitSections[I].Address)
+        InitSections[I].Address = CurrentTDataAddr;
+      break;
     }
 
     if (InitSections[I].SectionData.binary_size()) {
@@ -176,8 +175,8 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
         }
         CurrentOffset = InitSections[I].FileOffsetToData;
       } else {
-         CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
-         InitSections[I].FileOffsetToData = CurrentOffset;
+        CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
+        InitSections[I].FileOffsetToData = CurrentOffset;
       }
       CurrentOffset += InitSections[I].SectionData.binary_size();
       if (CurrentOffset > MaxRawDataSize) {
@@ -368,9 +367,10 @@ bool XCOFFWriter::assignAddressesAndIndices() {
   // If AuxHeaderSize is specified in the YAML file, we construct
   // an auxiliary header.
   const uint64_t AuxFileHdrSize =
-      Obj.Header.AuxHeaderSize ? *Obj.Header.AuxHeaderSize :
-      !Obj.AuxHeader ? 0 :
-      (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
+      Obj.Header.AuxHeaderSize ? *Obj.Header.AuxHeaderSize
+      : !Obj.AuxHeader
+          ? 0
+          : (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
   const uint64_t SecHdrSize =
       Is64Bit ? XCOFF::SectionHeaderSize64 : XCOFF::SectionHeaderSize32;
   uint64_t CurrentOffset =

>From f54af06a36276f8d2b3f8f8e1531d529c1108bb3 Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Tue, 16 Jan 2024 18:42:11 -0500
Subject: [PATCH 3/5] Clean up code; add testcase

---
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp          |  94 +++++++----
 .../tools/yaml2obj/XCOFF/offset-check.yaml    | 156 ++++++++++++++++++
 2 files changed, 216 insertions(+), 34 deletions(-)
 create mode 100644 llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml

diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index 7a45dc8a67d4e1..40f47c9aabdc1b 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -40,6 +40,8 @@ class XCOFFWriter {
   bool writeXCOFF();
 
 private:
+  void ErrOverwrite(uint64_t currentOffset, uint64_t specifiedOffset,
+                    const Twine &fieldName);
   bool nameShouldBeInStringTable(StringRef SymbolName);
   bool initFileHeader(uint64_t CurrentOffset);
   void initAuxFileHeader();
@@ -90,6 +92,13 @@ static void writeName(StringRef StrName, support::endian::Writer W) {
   W.write(NameRef);
 }
 
+void XCOFFWriter::ErrOverwrite(uint64_t CurrentOffset, uint64_t specifiedOffset,
+                               const Twine &fieldName) {
+  ErrHandler("current file offset (" + Twine(CurrentOffset) +
+             ") is bigger than the specified " + fieldName + " (" +
+             Twine(specifiedOffset) + ") ");
+}
+
 bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {
   // For XCOFF64: The symbol name is always in the string table.
   return (SymbolName.size() > XCOFF::NameSize) || Is64Bit;
@@ -100,18 +109,19 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
     if (!InitSection.Relocations.empty()) {
       uint64_t RelSize = Is64Bit ? XCOFF::RelocationSerializationSize64
                                  : XCOFF::RelocationSerializationSize32;
-      const uint64_t UsedSize = RelSize * InitSection.Relocations.size();
+      uint64_t UsedSize = RelSize * InitSection.Relocations.size();
 
       // If NumberOfRelocations was specified, we use it, even if it's
-      // not consistent with the number of provided relocations
+      // not consistent with the number of provided relocations.
       if (!InitSection.NumberOfRelocations)
         InitSection.NumberOfRelocations = InitSection.Relocations.size();
 
       // If the YAML file specified an offset to relocations, we use it.
       if (InitSection.FileOffsetToRelocations) {
         if (CurrentOffset > InitSection.FileOffsetToRelocations) {
-          ErrHandler("Specified FileOffsetToRelocations will overwrite"
-                     "existing data");
+          ErrOverwrite(CurrentOffset, InitSection.FileOffsetToRelocations,
+                       "FileOffsetToRelocations for the " +
+                           InitSection.SectionName + " section");
           return false;
         }
         CurrentOffset = InitSection.FileOffsetToRelocations;
@@ -119,8 +129,9 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
         InitSection.FileOffsetToRelocations = CurrentOffset;
       CurrentOffset += UsedSize;
       if (CurrentOffset > MaxRawDataSize) {
-        ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
-                   "exceeded when writing relocation data");
+        ErrHandler("maximum object size (" + Twine(MaxRawDataSize) +
+                   ") exceeded when writing relocation data for section " +
+                   Twine(InitSection.SectionName));
         return false;
       }
     }
@@ -129,8 +140,8 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
 }
 
 bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
-  uint64_t CurrentDataAddr = 0;
-  uint64_t CurrentTDataAddr = 0;
+  uint64_t CurrentEndDataAddr = 0;
+  uint64_t CurrentEndTDataAddr = 0;
   for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
     // Assign indices for sections.
     if (InitSections[I].SectionName.size() &&
@@ -147,22 +158,31 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
     if (!InitSections[I].Size)
       InitSections[I].Size = InitSections[I].SectionData.binary_size();
 
-    // We cannot compute section addresses in general. We only enforce
-    // the rule .data and .bss are consecutive, as are .tdata and .tbss.
+    // Section data addresses (physical/virtual) are related to symbol
+    // addresses and alignments. Furthermore, it is possible to specify the
+    // same starting addresses for the .text, .data, and .tdata sections.
+    // Without examining all the symbols and their addreses and alignments,
+    // it is not possible to compute valid section addresses. The only
+    // condition required by XCOFF is that the .bss section immediately
+    // follows the .data section, and the .tbss section immediately follows
+    // the .tdata section. Therefore, we only assign addresses to the .bss
+    // and .tbss sections if they do not already have non-zero addresses.
+    // (If the YAML file is being used to generate a valid object file, we
+    // expect all section addresses to be specified explicitly.)
     switch (InitSections[I].Flags) {
     case XCOFF::STYP_DATA:
-      CurrentDataAddr = InitSections[I].Address + InitSections[I].Size;
+      CurrentEndDataAddr = InitSections[I].Address + InitSections[I].Size;
       break;
     case XCOFF::STYP_BSS:
       if (!InitSections[I].Address)
-        InitSections[I].Address = CurrentDataAddr;
+        InitSections[I].Address = CurrentEndDataAddr;
       break;
     case XCOFF::STYP_TDATA:
-      CurrentTDataAddr = InitSections[I].Address + InitSections[I].Size;
+      CurrentEndTDataAddr = InitSections[I].Address + InitSections[I].Size;
       break;
     case XCOFF::STYP_TBSS:
       if (!InitSections[I].Address)
-        InitSections[I].Address = CurrentTDataAddr;
+        InitSections[I].Address = CurrentEndTDataAddr;
       break;
     }
 
@@ -170,7 +190,9 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
       if (InitSections[I].FileOffsetToData) {
         // Use the providedFileOffsetToData.
         if (CurrentOffset > InitSections[I].FileOffsetToData) {
-          ErrHandler("Specified FileOffsetToData will overwrite existing data");
+          ErrOverwrite(CurrentOffset, InitSections[I].FileOffsetToData,
+                       "FileOffsetToData for the " +
+                           InitSections[I].SectionName + " section");
           return false;
         }
         CurrentOffset = InitSections[I].FileOffsetToData;
@@ -180,8 +202,9 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
       }
       CurrentOffset += InitSections[I].SectionData.binary_size();
       if (CurrentOffset > MaxRawDataSize) {
-        ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
-                   "exceeded when writing section data");
+        ErrHandler("maximum object size (" + Twine(MaxRawDataSize) +
+                   ") exceeded when writing data for section " + Twine(I + 1) +
+                   " (" + Twine(InitSections[I].SectionName) + ")");
         return false;
       }
     }
@@ -289,7 +312,8 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
   if (InitFileHdr.NumberOfSymTableEntries) {
     if (Obj.Header.SymbolTableOffset) {
       if (CurrentOffset > Obj.Header.SymbolTableOffset) {
-        ErrHandler("symbol table offset overlaps existing data");
+        ErrOverwrite(CurrentOffset, Obj.Header.SymbolTableOffset,
+                     "SymbolTableOffset");
         return false;
       }
       CurrentOffset = Obj.Header.SymbolTableOffset;
@@ -298,8 +322,8 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
     CurrentOffset +=
         InitFileHdr.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;
     if (CurrentOffset > MaxRawDataSize) {
-      ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
-                 "exceeded when writing symbols");
+      ErrHandler("maximum object size of " + Twine(MaxRawDataSize) +
+                 " exceeded when writing symbols");
       return false;
     }
   }
@@ -361,17 +385,19 @@ void XCOFFWriter::initAuxFileHeader() {
 }
 
 bool XCOFFWriter::assignAddressesAndIndices() {
-  const uint64_t FileHdrSize =
+  uint64_t FileHdrSize =
       Is64Bit ? XCOFF::FileHeaderSize64 : XCOFF::FileHeaderSize32;
 
   // If AuxHeaderSize is specified in the YAML file, we construct
   // an auxiliary header.
-  const uint64_t AuxFileHdrSize =
-      Obj.Header.AuxHeaderSize ? *Obj.Header.AuxHeaderSize
-      : !Obj.AuxHeader
-          ? 0
-          : (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
-  const uint64_t SecHdrSize =
+  uint64_t AuxFileHdrSize = 0;
+
+  if (Obj.Header.AuxHeaderSize)
+    AuxFileHdrSize = *Obj.Header.AuxHeaderSize;
+  else if (Obj.AuxHeader)
+    AuxFileHdrSize =
+        (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
+  uint64_t SecHdrSize =
       Is64Bit ? XCOFF::SectionHeaderSize64 : XCOFF::SectionHeaderSize32;
   uint64_t CurrentOffset =
       FileHdrSize + AuxFileHdrSize + InitSections.size() * SecHdrSize;
@@ -495,7 +521,7 @@ void XCOFFWriter::writeSectionHeaders() {
       W.write<uint64_t>(DerivedSec.FileOffsetToLineNumbers);
       W.write<uint32_t>(DerivedSec.NumberOfRelocations);
       W.write<uint32_t>(DerivedSec.NumberOfLineNumbers);
-      W.write<int32_t>(YamlSec.Flags);
+      W.write<int32_t>(DerivedSec.Flags);
       W.OS.write_zeros(4);
     } else {
       // Virtual address is the same as physical address.
@@ -507,7 +533,7 @@ void XCOFFWriter::writeSectionHeaders() {
       W.write<uint32_t>(DerivedSec.FileOffsetToLineNumbers);
       W.write<uint16_t>(DerivedSec.NumberOfRelocations);
       W.write<uint16_t>(DerivedSec.NumberOfLineNumbers);
-      W.write<int32_t>(YamlSec.Flags);
+      W.write<int32_t>(DerivedSec.Flags);
     }
   }
 }
@@ -517,10 +543,10 @@ bool XCOFFWriter::writeSectionData() {
     XCOFFYAML::Section YamlSec = Obj.Sections[I];
     if (YamlSec.SectionData.binary_size()) {
       // Fill the padding size with zeros.
-      int64_t PaddingSize =
-          InitSections[I].FileOffsetToData - (W.OS.tell() - StartOffset);
+      int64_t PaddingSize = (uint64_t)InitSections[I].FileOffsetToData -
+                            (W.OS.tell() - StartOffset);
       if (PaddingSize < 0) {
-        ErrHandler("redundant data was written before section data");
+        ErrHandler("unexpected data was written before section data");
         return false;
       }
       W.OS.write_zeros(PaddingSize);
@@ -537,7 +563,7 @@ bool XCOFFWriter::writeRelocations() {
       int64_t PaddingSize =
           InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset);
       if (PaddingSize < 0) {
-        ErrHandler("redundant data was written before relocations");
+        ErrHandler("unexpected data was written before relocations");
         return false;
       }
       W.OS.write_zeros(PaddingSize);
@@ -678,7 +704,7 @@ bool XCOFFWriter::writeSymbols() {
   int64_t PaddingSize =
       InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
   if (PaddingSize < 0) {
-    ErrHandler("redundant data was written before symbols");
+    ErrHandler("unexpected data was written before symbols");
     return false;
   }
   W.OS.write_zeros(PaddingSize);
diff --git a/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml b/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml
new file mode 100644
index 00000000000000..7e7c93bf383f66
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml
@@ -0,0 +1,156 @@
+## Case 1: an error is reported when FileOffsetToData is too small
+## RUN: not yaml2obj --docnum=1 %s -o %t 2>&1 | \
+## RUN:   FileCheck %s --check-prefix=ERROR1
+#
+# ERROR1: error: current file offset (60) is bigger than the specified FileOffsetToData for the .text section (48)
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1DF
+  NumberOfSections: 1
+  CreationTime:    1705445558
+  OffsetToSymbolTable: 0x4E
+  AuxiliaryHeaderSize: 0
+  Flags:           0x0
+Sections:
+  - Name:            .text
+    Address:         0x0
+    Size:            0x8
+    FileOffsetToData: 0x30
+    FileOffsetToRelocations: 0x44
+    NumberOfRelocations: 0x1
+    Flags:           [ STYP_TEXT ]
+    SectionData:     '480000014E800020'
+    Relocations:
+      - Address:         0x0
+        Symbol:          0x0
+        Info:            0x99
+        Type:            0x1A
+Symbols:
+  - Name:            .bar
+    Value:           0x0
+    Section:         N_UNDEF
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 0
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 0
+  - Name:            .foo
+    Value:           0x0
+    Section:         .text
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 17
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 8
+StringTable:     {}
+...
+## Case 2: an error is reported when FileOffsetToRelocations is too small
+## RUN: not yaml2obj --docnum=2 %s -o %t 2>&1 | \
+## RUN:   FileCheck %s --check-prefix=ERROR2
+#
+# ERROR2: current file offset (68) is bigger than the specified FileOffsetToRelocations for the .text section (64) 
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1DF
+  NumberOfSections: 1
+  CreationTime:    1705445558
+  OffsetToSymbolTable: 0x4E
+  AuxiliaryHeaderSize: 0
+  Flags:           0x0
+Sections:
+  - Name:            .text
+    Address:         0x0
+    Size:            0x8
+    FileOffsetToData: 0x3C
+    FileOffsetToRelocations: 0x40
+    NumberOfRelocations: 0x1
+    Flags:           [ STYP_TEXT ]
+    SectionData:     '480000014E800020'
+    Relocations:
+      - Address:         0x0
+        Symbol:          0x0
+        Info:            0x99
+        Type:            0x1A
+Symbols:
+  - Name:            .bar
+    Value:           0x0
+    Section:         N_UNDEF
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 0
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 0
+  - Name:            .foo
+    Value:           0x0
+    Section:         .text
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 17
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 8
+StringTable:     {}
+...
+## Case 1: an error is reported when the OffsetToSymbolTable is too small
+## RUN: not yaml2obj --docnum=3 %s -o %t 2>&1 | \
+## RUN:   FileCheck %s --check-prefix=ERROR3
+#
+# ERROR3: current file offset (78) is bigger than the specified SymbolTableOffset (64) 
+--- !XCOFF
+FileHeader:
+  MagicNumber:     0x1DF
+  NumberOfSections: 1
+  CreationTime:    1705445558
+  OffsetToSymbolTable: 0x40
+  AuxiliaryHeaderSize: 0
+  Flags:           0x0
+Sections:
+  - Name:            .text
+    Address:         0x0
+    Size:            0x8
+    FileOffsetToData: 0x3C
+    FileOffsetToRelocations: 0x44
+    NumberOfRelocations: 0x1
+    Flags:           [ STYP_TEXT ]
+    SectionData:     '480000014E800020'
+    Relocations:
+      - Address:         0x0
+        Symbol:          0x0
+        Info:            0x99
+        Type:            0x1A
+Symbols:
+  - Name:            .bar
+    Value:           0x0
+    Section:         N_UNDEF
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 0
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 0
+  - Name:            .foo
+    Value:           0x0
+    Section:         .text
+    Type:            0x0
+    StorageClass:    C_EXT
+    NumberOfAuxEntries: 1
+    AuxEntries:
+      - Type:            AUX_CSECT
+        SymbolAlignmentAndType: 17
+        StorageMappingClass: XMC_PR
+        SectionOrLength: 8
+StringTable:     {}
+...

>From b3ff586ce8ab6fa2ec15a4e1ee3b486ac9c554ce Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Mon, 29 Jan 2024 16:01:08 -0500
Subject: [PATCH 4/5] Updated based on review comments

---
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp          |  31 ++--
 .../tools/yaml2obj/XCOFF/offset-check.yaml    | 153 +++++-------------
 2 files changed, 60 insertions(+), 124 deletions(-)

diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index 40f47c9aabdc1b..46e108bf118384 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -40,8 +40,8 @@ class XCOFFWriter {
   bool writeXCOFF();
 
 private:
-  void ErrOverwrite(uint64_t currentOffset, uint64_t specifiedOffset,
-                    const Twine &fieldName);
+  void reportOverwrite(uint64_t currentOffset, uint64_t specifiedOffset,
+                       const Twine &fieldName);
   bool nameShouldBeInStringTable(StringRef SymbolName);
   bool initFileHeader(uint64_t CurrentOffset);
   void initAuxFileHeader();
@@ -92,8 +92,9 @@ static void writeName(StringRef StrName, support::endian::Writer W) {
   W.write(NameRef);
 }
 
-void XCOFFWriter::ErrOverwrite(uint64_t CurrentOffset, uint64_t specifiedOffset,
-                               const Twine &fieldName) {
+void XCOFFWriter::reportOverwrite(uint64_t CurrentOffset,
+                                  uint64_t specifiedOffset,
+                                  const Twine &fieldName) {
   ErrHandler("current file offset (" + Twine(CurrentOffset) +
              ") is bigger than the specified " + fieldName + " (" +
              Twine(specifiedOffset) + ") ");
@@ -119,9 +120,9 @@ bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
       // If the YAML file specified an offset to relocations, we use it.
       if (InitSection.FileOffsetToRelocations) {
         if (CurrentOffset > InitSection.FileOffsetToRelocations) {
-          ErrOverwrite(CurrentOffset, InitSection.FileOffsetToRelocations,
-                       "FileOffsetToRelocations for the " +
-                           InitSection.SectionName + " section");
+          reportOverwrite(CurrentOffset, InitSection.FileOffsetToRelocations,
+                          "FileOffsetToRelocations for the " +
+                              InitSection.SectionName + " section");
           return false;
         }
         CurrentOffset = InitSection.FileOffsetToRelocations;
@@ -190,9 +191,9 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
       if (InitSections[I].FileOffsetToData) {
         // Use the providedFileOffsetToData.
         if (CurrentOffset > InitSections[I].FileOffsetToData) {
-          ErrOverwrite(CurrentOffset, InitSections[I].FileOffsetToData,
-                       "FileOffsetToData for the " +
-                           InitSections[I].SectionName + " section");
+          reportOverwrite(CurrentOffset, InitSections[I].FileOffsetToData,
+                          "FileOffsetToData for the " +
+                              InitSections[I].SectionName + " section");
           return false;
         }
         CurrentOffset = InitSections[I].FileOffsetToData;
@@ -312,8 +313,8 @@ bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
   if (InitFileHdr.NumberOfSymTableEntries) {
     if (Obj.Header.SymbolTableOffset) {
       if (CurrentOffset > Obj.Header.SymbolTableOffset) {
-        ErrOverwrite(CurrentOffset, Obj.Header.SymbolTableOffset,
-                     "SymbolTableOffset");
+        reportOverwrite(CurrentOffset, Obj.Header.SymbolTableOffset,
+                        "SymbolTableOffset");
         return false;
       }
       CurrentOffset = Obj.Header.SymbolTableOffset;
@@ -546,7 +547,7 @@ bool XCOFFWriter::writeSectionData() {
       int64_t PaddingSize = (uint64_t)InitSections[I].FileOffsetToData -
                             (W.OS.tell() - StartOffset);
       if (PaddingSize < 0) {
-        ErrHandler("unexpected data was written before section data");
+        ErrHandler("redundant data was written before section data");
         return false;
       }
       W.OS.write_zeros(PaddingSize);
@@ -563,7 +564,7 @@ bool XCOFFWriter::writeRelocations() {
       int64_t PaddingSize =
           InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset);
       if (PaddingSize < 0) {
-        ErrHandler("unexpected data was written before relocations");
+        ErrHandler("redundant data was written before relocations");
         return false;
       }
       W.OS.write_zeros(PaddingSize);
@@ -704,7 +705,7 @@ bool XCOFFWriter::writeSymbols() {
   int64_t PaddingSize =
       InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
   if (PaddingSize < 0) {
-    ErrHandler("unexpected data was written before symbols");
+    ErrHandler("redundant data was written before symbols");
     return false;
   }
   W.OS.write_zeros(PaddingSize);
diff --git a/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml b/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml
index 7e7c93bf383f66..ee23a16d8c162c 100644
--- a/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml
+++ b/llvm/test/tools/yaml2obj/XCOFF/offset-check.yaml
@@ -1,82 +1,58 @@
-## Case 1: an error is reported when FileOffsetToData is too small
-## RUN: not yaml2obj --docnum=1 %s -o %t 2>&1 | \
-## RUN:   FileCheck %s --check-prefix=ERROR1
-#
-# ERROR1: error: current file offset (60) is bigger than the specified FileOffsetToData for the .text section (48)
+## Report errors when specified file offsets are invalid.
+
+# RUN: not yaml2obj %s -DTEXTRAWDATAOFFSET=0xFFFFFFF0 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR1
+# ERROR1: current file offset (4294967288) is bigger than the specified FileOffsetToData for the .data section (108)
+
+# RUN: not yaml2obj %s -DDATARAWDATAOFFSET=0xFFFFFFF0 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR2
+# ERROR2: current file offset (4294967284) is bigger than the specified FileOffsetToRelocations for the .text section (112)
+
+# RUN: not yaml2obj %s -DRELOCOFFSET=0xFFFFFFF0 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR3
+# ERROR3: current file offset (4294967290) is bigger than the specified SymbolTableOffset (122)
+
+# RUN: not yaml2obj %s -DSYMTABOFFSET=0x100000000 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR4
+# ERROR4: maximum object size of 4294967295 exceeded when writing symbols
+
+# RUN: not yaml2obj %s -DRELOCOFFSET=0x100000000 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR5
+# ERROR5: maximum object size (4294967295) exceeded when writing relocation data for section .text
+
+# RUN: not yaml2obj %s -DDATARAWDATAOFFSET=0x100000000 -o %t 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ERROR6
+# ERROR6: maximum object size (4294967295) exceeded when writing data for section 2 (.data)
+
 --- !XCOFF
 FileHeader:
   MagicNumber:     0x1DF
-  NumberOfSections: 1
-  CreationTime:    1705445558
-  OffsetToSymbolTable: 0x4E
+  NumberOfSections: 2
+  OffsetToSymbolTable: [[SYMTABOFFSET=0x7A]]
+  EntriesInSymbolTable: 6
   AuxiliaryHeaderSize: 0
   Flags:           0x0
 Sections:
   - Name:            .text
     Address:         0x0
     Size:            0x8
-    FileOffsetToData: 0x30
-    FileOffsetToRelocations: 0x44
+    FileOffsetToData: [[TEXTRAWDATAOFFSET=0x64]]
+    FileOffsetToRelocations: [[RELOCOFFSET=0x70]]
     NumberOfRelocations: 0x1
     Flags:           [ STYP_TEXT ]
-    SectionData:     '480000014E800020'
+    SectionData:     386000004BFFFFFC
     Relocations:
-      - Address:         0x0
-        Symbol:          0x0
+      - Address:         0x4
+        Symbol:          0x2
         Info:            0x99
         Type:            0x1A
-Symbols:
-  - Name:            .bar
-    Value:           0x0
-    Section:         N_UNDEF
-    Type:            0x0
-    StorageClass:    C_EXT
-    NumberOfAuxEntries: 1
-    AuxEntries:
-      - Type:            AUX_CSECT
-        SymbolAlignmentAndType: 0
-        StorageMappingClass: XMC_PR
-        SectionOrLength: 0
-  - Name:            .foo
-    Value:           0x0
-    Section:         .text
-    Type:            0x0
-    StorageClass:    C_EXT
-    NumberOfAuxEntries: 1
-    AuxEntries:
-      - Type:            AUX_CSECT
-        SymbolAlignmentAndType: 17
-        StorageMappingClass: XMC_PR
-        SectionOrLength: 8
-StringTable:     {}
-...
-## Case 2: an error is reported when FileOffsetToRelocations is too small
-## RUN: not yaml2obj --docnum=2 %s -o %t 2>&1 | \
-## RUN:   FileCheck %s --check-prefix=ERROR2
-#
-# ERROR2: current file offset (68) is bigger than the specified FileOffsetToRelocations for the .text section (64) 
---- !XCOFF
-FileHeader:
-  MagicNumber:     0x1DF
-  NumberOfSections: 1
-  CreationTime:    1705445558
-  OffsetToSymbolTable: 0x4E
-  AuxiliaryHeaderSize: 0
-  Flags:           0x0
-Sections:
-  - Name:            .text
+  - Name:            .data
     Address:         0x0
-    Size:            0x8
-    FileOffsetToData: 0x3C
-    FileOffsetToRelocations: 0x40
-    NumberOfRelocations: 0x1
-    Flags:           [ STYP_TEXT ]
-    SectionData:     '480000014E800020'
-    Relocations:
-      - Address:         0x0
-        Symbol:          0x0
-        Info:            0x99
-        Type:            0x1A
+    Size:            0x4
+    FileOffsetToData: [[DATARAWDATAOFFSET=0x6C]]
+    FileOffsetToRelocations: 0
+    Flags:           [ STYP_DATA ]
+    SectionData:     3210ABCD
 Symbols:
   - Name:            .bar
     Value:           0x0
@@ -89,58 +65,17 @@ Symbols:
         SymbolAlignmentAndType: 0
         StorageMappingClass: XMC_PR
         SectionOrLength: 0
-  - Name:            .foo
+  - Name:            ''
     Value:           0x0
     Section:         .text
     Type:            0x0
-    StorageClass:    C_EXT
+    StorageClass:    C_HIDEXT
     NumberOfAuxEntries: 1
     AuxEntries:
       - Type:            AUX_CSECT
         SymbolAlignmentAndType: 17
         StorageMappingClass: XMC_PR
         SectionOrLength: 8
-StringTable:     {}
-...
-## Case 1: an error is reported when the OffsetToSymbolTable is too small
-## RUN: not yaml2obj --docnum=3 %s -o %t 2>&1 | \
-## RUN:   FileCheck %s --check-prefix=ERROR3
-#
-# ERROR3: current file offset (78) is bigger than the specified SymbolTableOffset (64) 
---- !XCOFF
-FileHeader:
-  MagicNumber:     0x1DF
-  NumberOfSections: 1
-  CreationTime:    1705445558
-  OffsetToSymbolTable: 0x40
-  AuxiliaryHeaderSize: 0
-  Flags:           0x0
-Sections:
-  - Name:            .text
-    Address:         0x0
-    Size:            0x8
-    FileOffsetToData: 0x3C
-    FileOffsetToRelocations: 0x44
-    NumberOfRelocations: 0x1
-    Flags:           [ STYP_TEXT ]
-    SectionData:     '480000014E800020'
-    Relocations:
-      - Address:         0x0
-        Symbol:          0x0
-        Info:            0x99
-        Type:            0x1A
-Symbols:
-  - Name:            .bar
-    Value:           0x0
-    Section:         N_UNDEF
-    Type:            0x0
-    StorageClass:    C_EXT
-    NumberOfAuxEntries: 1
-    AuxEntries:
-      - Type:            AUX_CSECT
-        SymbolAlignmentAndType: 0
-        StorageMappingClass: XMC_PR
-        SectionOrLength: 0
   - Name:            .foo
     Value:           0x0
     Section:         .text
@@ -149,8 +84,8 @@ Symbols:
     NumberOfAuxEntries: 1
     AuxEntries:
       - Type:            AUX_CSECT
-        SymbolAlignmentAndType: 17
+        SymbolAlignmentAndType: 2
         StorageMappingClass: XMC_PR
-        SectionOrLength: 8
+        SectionOrLength: 2
 StringTable:     {}
 ...

>From 5fbf95a953e06cd7180917f3af43f044e0dcaa95 Mon Sep 17 00:00:00 2001
From: Stephen Peckham <speckham at us.ibm.com>
Date: Wed, 7 Feb 2024 17:38:53 -0500
Subject: [PATCH 5/5] Undo optional on AuxHeaderSize

---
 llvm/include/llvm/ObjectYAML/XCOFFYAML.h |  2 +-
 llvm/lib/ObjectYAML/XCOFFEmitter.cpp     | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
index e4b6a5d2f8de17..f1e821fe5fa369 100644
--- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
@@ -26,7 +26,7 @@ struct FileHeader {
   int32_t TimeStamp;
   llvm::yaml::Hex64 SymbolTableOffset;
   int32_t NumberOfSymTableEntries;
-  std::optional<uint16_t> AuxHeaderSize;
+  uint16_t AuxHeaderSize;
   llvm::yaml::Hex16 Flags;
 };
 
diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index 46e108bf118384..12175e8e5acbac 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -394,7 +394,7 @@ bool XCOFFWriter::assignAddressesAndIndices() {
   uint64_t AuxFileHdrSize = 0;
 
   if (Obj.Header.AuxHeaderSize)
-    AuxFileHdrSize = *Obj.Header.AuxHeaderSize;
+    AuxFileHdrSize = Obj.Header.AuxHeaderSize;
   else if (Obj.AuxHeader)
     AuxFileHdrSize =
         (Is64Bit ? XCOFF::AuxFileHeaderSize64 : XCOFF::AuxFileHeaderSize32);
@@ -427,7 +427,7 @@ void XCOFFWriter::writeFileHeader() {
   W.write<int32_t>(Obj.Header.TimeStamp);
   if (Is64Bit) {
     W.write<uint64_t>(InitFileHdr.SymbolTableOffset);
-    W.write<uint16_t>(*InitFileHdr.AuxHeaderSize);
+    W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
     W.write<uint16_t>(Obj.Header.Flags);
     W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
                          ? Obj.Header.NumberOfSymTableEntries
@@ -437,7 +437,7 @@ void XCOFFWriter::writeFileHeader() {
     W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
                          ? Obj.Header.NumberOfSymTableEntries
                          : InitFileHdr.NumberOfSymTableEntries);
-    W.write<uint16_t>(*InitFileHdr.AuxHeaderSize);
+    W.write<uint16_t>(InitFileHdr.AuxHeaderSize);
     W.write<uint16_t>(Obj.Header.Flags);
   }
 }
@@ -458,7 +458,7 @@ void XCOFFWriter::writeAuxFileHeader() {
     W.write<uint32_t>(InitAuxFileHdr.TextStartAddr.value_or(yaml::Hex64(0)));
     W.write<uint32_t>(InitAuxFileHdr.DataStartAddr.value_or(yaml::Hex64(0)));
     // A short 32-bit auxiliary header ends here.
-    if (*InitFileHdr.AuxHeaderSize == XCOFF::AuxFileHeaderSizeShort)
+    if (InitFileHdr.AuxHeaderSize == XCOFF::AuxFileHeaderSizeShort)
       return;
     W.write<uint32_t>(InitAuxFileHdr.TOCAnchorAddr.value_or(yaml::Hex64(0)));
   }
@@ -501,10 +501,10 @@ void XCOFFWriter::writeAuxFileHeader() {
     W.write<uint16_t>(
         InitAuxFileHdr.Flag.value_or(yaml::Hex16(XCOFF::SHR_SYMTAB)));
     if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize64)
-      W.OS.write_zeros(*InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize64);
+      W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize64);
   } else {
     if (InitFileHdr.AuxHeaderSize > XCOFF::AuxFileHeaderSize32)
-      W.OS.write_zeros(*InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize32);
+      W.OS.write_zeros(InitFileHdr.AuxHeaderSize - XCOFF::AuxFileHeaderSize32);
   }
 }
 
@@ -814,7 +814,7 @@ bool XCOFFWriter::writeXCOFF() {
     return false;
   StartOffset = W.OS.tell();
   writeFileHeader();
-  if (InitFileHdr.AuxHeaderSize.value_or(0))
+  if (InitFileHdr.AuxHeaderSize)
     writeAuxFileHeader();
   if (!Obj.Sections.empty()) {
     writeSectionHeaders();



More information about the llvm-commits mailing list