[llvm] 6143ec2 - [NFC][XCOFF] Refactor and format XCOFFObjectWriter.cpp.

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 14 23:41:18 PDT 2022


Author: esmeyi
Date: 2022-03-15T02:40:50-04:00
New Revision: 6143ec2961d14c0b913d7687a0db209a9b26e39c

URL: https://github.com/llvm/llvm-project/commit/6143ec2961d14c0b913d7687a0db209a9b26e39c
DIFF: https://github.com/llvm/llvm-project/commit/6143ec2961d14c0b913d7687a0db209a9b26e39c.diff

LOG: [NFC][XCOFF] Refactor and format XCOFFObjectWriter.cpp.

Reviewed By: jhenderson, DiggerLin

Differential Revision: https://reviews.llvm.org/D120858

Added: 
    

Modified: 
    llvm/lib/MC/XCOFFObjectWriter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 4dfadc903a54a..8e695acf28b40 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -198,6 +198,9 @@ class XCOFFObjectWriter : public MCObjectWriter {
   std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
   StringTableBuilder Strings;
 
+  const uint64_t MaxRawDataSize =
+      TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;
+
   // Maps the MCSection representation to its corresponding XCOFFSection
   // wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into
   // from its containing MCSectionXCOFF.
@@ -245,14 +248,19 @@ class XCOFFObjectWriter : public MCObjectWriter {
 
   uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override;
 
+  bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
   static bool nameShouldBeInStringTable(const StringRef &);
   void writeSymbolName(const StringRef &);
-  void writeSymbolTableEntryForCsectMemberLabel(const Symbol &,
-                                                const XCOFFSection &, int16_t,
-                                                uint64_t);
-  void writeSymbolTableEntryForControlSection(const XCOFFSection &, int16_t,
-                                              XCOFF::StorageClass);
-  void writeSymbolTableEntryForDwarfSection(const XCOFFSection &, int16_t);
+
+  void writeSymbolEntryForCsectMemberLabel(const Symbol &SymbolRef,
+                                           const XCOFFSection &CSectionRef,
+                                           int16_t SectionIndex,
+                                           uint64_t SymbolOffset);
+  void writeSymbolEntryForControlSection(const XCOFFSection &CSectionRef,
+                                         int16_t SectionIndex,
+                                         XCOFF::StorageClass StorageClass);
+  void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,
+                                       int16_t SectionIndex);
   void writeFileHeader();
   void writeSectionHeaderTable();
   void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
@@ -265,6 +273,14 @@ class XCOFFObjectWriter : public MCObjectWriter {
                                         const DwarfSectionEntry &DwarfEntry,
                                         uint32_t &CurrentAddressLocation);
   void writeSymbolTable(const MCAsmLayout &Layout);
+  void writeSymbolAuxDwarfEntry(uint32_t LengthOfSectionPortion,
+                                uint32_t NumberOfRelocEnt = 0);
+  void writeSymbolAuxCsectEntry(uint32_t SectionOrLength,
+                                uint8_t SymbolAlignmentAndType,
+                                uint8_t StorageMappingClass);
+  void writeSymbolEntry(StringRef SymbolName, uint32_t Value,
+                        int16_t SectionNumber, uint16_t SymbolType,
+                        uint8_t StorageClass, uint8_t NumberOfAuxEntries = 1);
   void writeRelocations();
   void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &Section);
 
@@ -397,7 +413,7 @@ static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {
 
 void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
                                                  const MCAsmLayout &Layout) {
-  if (TargetObjectWriter->is64Bit())
+  if (is64Bit())
     report_fatal_error("64-bit XCOFF object files are not supported yet.");
 
   for (const auto &S : Asm) {
@@ -548,10 +564,9 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
     FixedValue = TOCEntryOffset;
   }
 
-  assert(
-      (TargetObjectWriter->is64Bit() ||
-       Fixup.getOffset() <= UINT32_MAX - Layout.getFragmentOffset(Fragment)) &&
-      "Fragment offset + fixup offset is overflowed in 32-bit mode.");
+  assert((Fixup.getOffset() <=
+          MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&
+         "Fragment offset + fixup offset is overflowed.");
   uint32_t FixupOffsetInCsect =
       Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
 
@@ -591,6 +606,7 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
 
 void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
                                       const MCAsmLayout &Layout) {
+  assert(!is64Bit() && "Writing 64-bit sections is not yet supported.");
   uint32_t CurrentAddressLocation = 0;
   for (const auto *Section : Sections)
     writeSectionForControlSectionEntry(Asm, Layout, *Section,
@@ -608,7 +624,7 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
   if (Asm.isIncrementalLinkerCompatible())
     report_fatal_error("Incremental linking not supported for XCOFF.");
 
-  if (TargetObjectWriter->is64Bit())
+  if (is64Bit())
     report_fatal_error("64-bit XCOFF object files are not supported yet.");
 
   finalizeSectionInfo();
@@ -631,26 +647,26 @@ bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
 }
 
 void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
+  // Magic, Offset or SymbolName.
   if (nameShouldBeInStringTable(SymbolName)) {
     W.write<int32_t>(0);
     W.write<uint32_t>(Strings.getOffset(SymbolName));
   } else {
-    char Name[XCOFF::NameSize+1];
+    char Name[XCOFF::NameSize + 1];
     std::strncpy(Name, SymbolName.data(), XCOFF::NameSize);
     ArrayRef<char> NameRef(Name, XCOFF::NameSize);
     W.write(NameRef);
   }
 }
 
-void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel(
-    const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
-    int16_t SectionIndex, uint64_t SymbolOffset) {
-  // Name or Zeros and string table offset
-  writeSymbolName(SymbolRef.getSymbolTableName());
-  assert(SymbolOffset <= UINT32_MAX - CSectionRef.Address &&
-         "Symbol address overflows.");
-  W.write<uint32_t>(CSectionRef.Address + SymbolOffset);
-  W.write<int16_t>(SectionIndex);
+void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint32_t Value,
+                                         int16_t SectionNumber,
+                                         uint16_t SymbolType,
+                                         uint8_t StorageClass,
+                                         uint8_t NumberOfAuxEntries) {
+  writeSymbolName(SymbolName);
+  W.write<uint32_t>(Value);
+  W.write<int16_t>(SectionNumber);
   // Basic/Derived type. See the description of the n_type field for symbol
   // table entries for a detailed description. Since we don't yet support
   // visibility, and all other bits are either optionally set or reserved, this
@@ -658,114 +674,78 @@ void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel(
   // TODO FIXME How to assert a symbol's visibilty is default?
   // TODO Set the function indicator (bit 10, 0x0020) for functions
   // when debugging is enabled.
-  W.write<uint16_t>(0);
-  W.write<uint8_t>(SymbolRef.getStorageClass());
-  // Always 1 aux entry for now.
-  W.write<uint8_t>(1);
-
-  // Now output the auxiliary entry.
-  W.write<uint32_t>(CSectionRef.SymbolTableIndex);
-  // Parameter typecheck hash. Not supported.
-  W.write<uint32_t>(0);
-  // Typecheck section number. Not supported.
-  W.write<uint16_t>(0);
-  // Symbol type: Label
-  W.write<uint8_t>(XCOFF::XTY_LD);
-  // Storage mapping class.
-  W.write<uint8_t>(CSectionRef.MCSec->getMappingClass());
-  // Reserved (x_stab).
-  W.write<uint32_t>(0);
-  // Reserved (x_snstab).
-  W.write<uint16_t>(0);
+  W.write<uint16_t>(SymbolType);
+  W.write<uint8_t>(StorageClass);
+  W.write<uint8_t>(NumberOfAuxEntries);
+}
+
+void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint32_t SectionOrLength,
+                                                 uint8_t SymbolAlignmentAndType,
+                                                 uint8_t StorageMappingClass) {
+  W.write<uint32_t>(SectionOrLength);
+  W.write<uint32_t>(0); // ParameterHashIndex
+  W.write<uint16_t>(0); // TypeChkSectNum
+  W.write<uint8_t>(SymbolAlignmentAndType);
+  W.write<uint8_t>(StorageMappingClass);
+  W.write<uint32_t>(0); // StabInfoIndex
+  W.write<uint16_t>(0); // StabSectNum
+}
+
+void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
+    uint32_t LengthOfSectionPortion, uint32_t NumberOfRelocEnt) {
+  W.write<uint32_t>(LengthOfSectionPortion);
+  W.OS.write_zeros(4); // Reserved
+  W.write<uint32_t>(NumberOfRelocEnt);
+  W.OS.write_zeros(6); // Reserved
+}
+
+void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
+    const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
+    int16_t SectionIndex, uint64_t SymbolOffset) {
+  assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
+         "Symbol address overflowed.");
+
+  writeSymbolEntry(SymbolRef.getSymbolTableName(),
+                   CSectionRef.Address + SymbolOffset, SectionIndex,
+                   /*SymbolType=*/0, SymbolRef.getStorageClass());
+
+  writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex, XCOFF::XTY_LD,
+                           CSectionRef.MCSec->getMappingClass());
 }
 
-void XCOFFObjectWriter::writeSymbolTableEntryForDwarfSection(
+void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
     const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
   assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");
 
-  // n_name, n_zeros, n_offset
-  writeSymbolName(DwarfSectionRef.getSymbolTableName());
-  // n_value
-  W.write<uint32_t>(0);
-  // n_scnum
-  W.write<int16_t>(SectionIndex);
-  // n_type
-  W.write<uint16_t>(0);
-  // n_sclass
-  W.write<uint8_t>(XCOFF::C_DWARF);
-  // Always 1 aux entry for now.
-  W.write<uint8_t>(1);
-
-  // Now output the auxiliary entry.
-  // x_scnlen
-  W.write<uint32_t>(DwarfSectionRef.Size);
-  // Reserved
-  W.write<uint32_t>(0);
-  // x_nreloc. Set to 0 for now.
-  W.write<uint32_t>(0);
-  // Reserved
-  W.write<uint32_t>(0);
-  // Reserved
-  W.write<uint16_t>(0);
+  writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), /*Value=*/0,
+                   SectionIndex, /*SymbolType=*/0, XCOFF::C_DWARF);
+
+  writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
 }
 
-void XCOFFObjectWriter::writeSymbolTableEntryForControlSection(
+void XCOFFObjectWriter::writeSymbolEntryForControlSection(
     const XCOFFSection &CSectionRef, int16_t SectionIndex,
     XCOFF::StorageClass StorageClass) {
-  // n_name, n_zeros, n_offset
-  writeSymbolName(CSectionRef.getSymbolTableName());
-  // n_value
-  W.write<uint32_t>(CSectionRef.Address);
-  // n_scnum
-  W.write<int16_t>(SectionIndex);
-  // Basic/Derived type. See the description of the n_type field for symbol
-  // table entries for a detailed description. Since we don't yet support
-  // visibility, and all other bits are either optionally set or reserved, this
-  // is always zero.
-  // TODO FIXME How to assert a symbol's visibilty is default?
-  // TODO Set the function indicator (bit 10, 0x0020) for functions
-  // when debugging is enabled.
-  W.write<uint16_t>(0);
-  // n_sclass
-  W.write<uint8_t>(StorageClass);
-  // Always 1 aux entry for now.
-  W.write<uint8_t>(1);
-
-  // Now output the auxiliary entry.
-  W.write<uint32_t>(CSectionRef.Size);
-  // Parameter typecheck hash. Not supported.
-  W.write<uint32_t>(0);
-  // Typecheck section number. Not supported.
-  W.write<uint16_t>(0);
-  // Symbol type.
-  W.write<uint8_t>(getEncodedType(CSectionRef.MCSec));
-  // Storage mapping class.
-  W.write<uint8_t>(CSectionRef.MCSec->getMappingClass());
-  // Reserved (x_stab).
-  W.write<uint32_t>(0);
-  // Reserved (x_snstab).
-  W.write<uint16_t>(0);
+  writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
+                   SectionIndex, /*SymbolType=*/0, StorageClass);
+
+  writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),
+                           CSectionRef.MCSec->getMappingClass());
 }
 
 void XCOFFObjectWriter::writeFileHeader() {
-  // Magic.
-  W.write<uint16_t>(0x01df);
-  // Number of sections.
+  assert(!is64Bit() && "Writing 64-bit file header is not yet supported.");
+  W.write<uint16_t>(XCOFF::XCOFF32);
   W.write<uint16_t>(SectionCount);
-  // Timestamp field. For reproducible output we write a 0, which represents no
-  // timestamp.
-  W.write<int32_t>(0);
-  // Byte Offset to the start of the symbol table.
+  W.write<int32_t>(0); // TimeStamp
   W.write<uint32_t>(SymbolTableOffset);
-  // Number of entries in the symbol table.
   W.write<int32_t>(SymbolTableEntryCount);
-  // Size of the optional header.
-  W.write<uint16_t>(0);
-  // Flags.
-  W.write<uint16_t>(0);
+  W.write<uint16_t>(0); // AuxHeaderSize
+  W.write<uint16_t>(0); // Flags
 }
 
 void XCOFFObjectWriter::writeSectionHeaderTable() {
+  assert(!is64Bit() && "Writing 64-bit section headers is not yet supported.");
   auto writeSectionHeader = [&](const SectionEntry *Sec, bool IsDwarf) {
     // Nothing to write for this Section.
     if (Sec->Index == SectionEntry::UninitializedIndex)
@@ -778,26 +758,16 @@ void XCOFFObjectWriter::writeSectionHeaderTable() {
     // Write the Physical Address and Virtual Address. In an object file these
     // are the same.
     // We use 0 for DWARF sections' Physical and Virtual Addresses.
-    if (!IsDwarf) {
-      W.write<uint32_t>(Sec->Address);
-      W.write<uint32_t>(Sec->Address);
-    } else {
-      W.write<uint32_t>(0);
-      W.write<uint32_t>(0);
-    }
+    W.write<uint32_t>(IsDwarf ? 0 : Sec->Address);
+    W.write<uint32_t>(IsDwarf ? 0 : Sec->Address);
 
     W.write<uint32_t>(Sec->Size);
     W.write<uint32_t>(Sec->FileOffsetToData);
     W.write<uint32_t>(Sec->FileOffsetToRelocations);
-
-    // Line number pointer. Not supported yet.
-    W.write<uint32_t>(0);
+    W.write<uint32_t>(0); // FileOffsetToLineNumberInfo. Not supported yet.
 
     W.write<uint16_t>(Sec->RelocationCount);
-
-    // Line number counts. Not supported yet.
-    W.write<uint16_t>(0);
-
+    W.write<uint16_t>(0); // NumberOfLineNumbers. Not supported yet.
     W.write<int32_t>(Sec->Flags);
 
     return true;
@@ -811,6 +781,7 @@ void XCOFFObjectWriter::writeSectionHeaderTable() {
 
 void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
                                         const XCOFFSection &Section) {
+  assert(!is64Bit() && "Writing 64-bit relocation is not yet supported.");
   if (Section.MCSec->isCsect())
     W.write<uint32_t>(Section.Address + Reloc.FixupOffsetInCsect);
   else {
@@ -846,34 +817,20 @@ void XCOFFObjectWriter::writeRelocations() {
 }
 
 void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
+  assert(!is64Bit() && "Writing 64-bit symbol table is not yet supported.");
   // Write symbol 0 as C_FILE.
   // FIXME: support 64-bit C_FILE symbol.
-  //
-  // n_name. The n_name of a C_FILE symbol is the source filename when no
-  // auxiliary entries are present. The source filename is alternatively
-  // provided by an auxiliary entry, in which case the n_name of the C_FILE
-  // symbol is `.file`.
-  // FIXME: add the real source filename.
-  writeSymbolName(".file");
-  // n_value. The n_value of a C_FILE symbol is its symbol table index.
-  W.write<uint32_t>(0);
-  // n_scnum. N_DEBUG is a reserved section number for indicating a special
-  // symbolic debugging symbol.
-  W.write<int16_t>(XCOFF::ReservedSectionNum::N_DEBUG);
-  // n_type. The n_type field of a C_FILE symbol encodes the source language and
-  // CPU version info; zero indicates no info.
-  W.write<uint16_t>(0);
-  // n_sclass. The C_FILE symbol provides source file-name information,
-  // source-language ID and CPU-version ID information and some other optional
-  // infos.
-  W.write<uint8_t>(XCOFF::C_FILE);
-  // n_numaux. No aux entry for now.
-  W.write<uint8_t>(0);
+  // The n_name of a C_FILE symbol is the source file's name when no auxiliary
+  // entries are present. The source file's name is alternatively provided by an
+  // auxiliary entry, in which case the n_name of the C_FILE symbol is `.file`.
+  // FIXME: add the real source file's name.
+  writeSymbolEntry(".file", /*Value=*/0, XCOFF::ReservedSectionNum::N_DEBUG,
+                   /*SymbolType=*/0, XCOFF::C_FILE,
+                   /*NumberOfAuxEntries=*/0);
 
   for (const auto &Csect : UndefinedCsects) {
-    writeSymbolTableEntryForControlSection(Csect,
-                                           XCOFF::ReservedSectionNum::N_UNDEF,
-                                           Csect.MCSec->getStorageClass());
+    writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,
+                                      Csect.MCSec->getStorageClass());
   }
 
   for (const auto *Section : Sections) {
@@ -888,19 +845,19 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
       const int16_t SectionIndex = Section->Index;
       for (const auto &Csect : *Group) {
         // Write out the control section first and then each symbol in it.
-        writeSymbolTableEntryForControlSection(Csect, SectionIndex,
-                                               Csect.MCSec->getStorageClass());
+        writeSymbolEntryForControlSection(Csect, SectionIndex,
+                                          Csect.MCSec->getStorageClass());
 
         for (const auto &Sym : Csect.Syms)
-          writeSymbolTableEntryForCsectMemberLabel(
+          writeSymbolEntryForCsectMemberLabel(
               Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym)));
       }
     }
   }
 
   for (const auto &DwarfSection : DwarfSections)
-    writeSymbolTableEntryForDwarfSection(*DwarfSection.DwarfSect,
-                                         DwarfSection.Index);
+    writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,
+                                    DwarfSection.Index);
 }
 
 void XCOFFObjectWriter::finalizeSectionInfo() {
@@ -942,7 +899,7 @@ void XCOFFObjectWriter::finalizeSectionInfo() {
     const uint32_t RelocationSizeInSec =
         Sec->RelocationCount * XCOFF::RelocationSerializationSize32;
     RawPointer += RelocationSizeInSec;
-    if (RawPointer > UINT32_MAX)
+    if (RawPointer > MaxRawDataSize)
       report_fatal_error("Relocation data overflowed this object file.");
 
     return true;
@@ -1082,7 +1039,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
 
     Sec->FileOffsetToData = RawPointer;
     RawPointer += Sec->Size;
-    if (RawPointer > UINT32_MAX)
+    if (RawPointer > MaxRawDataSize)
       report_fatal_error("Section raw data overflowed this object file.");
   }
 
@@ -1091,7 +1048,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
     // address of DWARF section are aligned to Section alignment which may be
     // bigger than DefaultSectionAlign, need to execlude the padding bits.
     RawPointer =
-          alignTo(RawPointer, DwarfSection.DwarfSect->MCSec->getAlignment());
+        alignTo(RawPointer, DwarfSection.DwarfSect->MCSec->getAlignment());
 
     DwarfSection.FileOffsetToData = RawPointer;
     // Some section entries, like DWARF section size is not aligned, so
@@ -1100,7 +1057,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
     // Make sure RawPointer is aligned.
     RawPointer = alignTo(RawPointer, DefaultSectionAlign);
 
-    assert(RawPointer <= UINT32_MAX &&
+    assert(RawPointer <= MaxRawDataSize &&
            "Section raw data overflowed this object file.");
   }
 


        


More information about the llvm-commits mailing list