[llvm] b1847ff - [XCOFF] write the aux header when the visibility is specified in XCOFF32.

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 04:11:02 PDT 2022


Author: esmeyi
Date: 2022-07-20T07:09:34-04:00
New Revision: b1847ff0686e7c43ebf6dc81cb08f8ca3305ab69

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

LOG: [XCOFF] write the aux header when the visibility is specified in XCOFF32.

The n_type field in the symbol table entry has two interpretations in XCOFF32, and a single interpretation in XCOFF64.
The new interpretation is used in XCOFF32 if the value of the o_vstamp field in the auxiliary header is 2.
In XCOFF64 and the new XCOFF32 interpretation, the n_type field is used for the symbol type and visibility.
The patch writes the aux header with an o_vstamp field value of 2 when the visibility is specified in XCOFF32 to make the new XCOFF32 interpretation used.

Reviewed By: DiggerLin, jhenderson

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

Added: 
    llvm/test/CodeGen/PowerPC/aix-aux-header.ll

Modified: 
    llvm/include/llvm/BinaryFormat/XCOFF.h
    llvm/lib/MC/XCOFFObjectWriter.cpp
    llvm/test/CodeGen/PowerPC/aix-xcoff-visibility.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index 5d23ec5cd911f..51e377293e953 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -31,6 +31,7 @@ constexpr size_t FileHeaderSize32 = 20;
 constexpr size_t FileHeaderSize64 = 24;
 constexpr size_t AuxFileHeaderSize32 = 72;
 constexpr size_t AuxFileHeaderSize64 = 110;
+constexpr size_t AuxFileHeaderSizeShort = 28;
 constexpr size_t SectionHeaderSize32 = 40;
 constexpr size_t SectionHeaderSize64 = 72;
 constexpr size_t SymbolTableEntrySize = 18;

diff  --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 977e77bf67fda..d46ae2247535d 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -206,6 +206,7 @@ class XCOFFObjectWriter : public MCObjectWriter {
   uint16_t SectionCount = 0;
   uint64_t RelocationEntryOffset = 0;
   std::vector<std::pair<std::string, size_t>> FileNames;
+  bool HasVisibility = false;
 
   support::endian::Writer W;
   std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
@@ -275,6 +276,7 @@ class XCOFFObjectWriter : public MCObjectWriter {
   void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,
                                        int16_t SectionIndex);
   void writeFileHeader();
+  void writeAuxFileHeader();
   void writeSectionHeaderTable();
   void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
   void writeSectionForControlSectionEntry(const MCAssembler &Asm,
@@ -308,14 +310,9 @@ class XCOFFObjectWriter : public MCObjectWriter {
   void assignAddressesAndIndices(const MCAsmLayout &);
   void finalizeSectionInfo();
 
-  // TODO aux header support not implemented.
-  bool needsAuxiliaryHeader() const { return false; }
-
-  // Returns the size of the auxiliary header to be written to the object file.
   size_t auxiliaryHeaderSize() const {
-    assert(!needsAuxiliaryHeader() &&
-           "Auxiliary header support not implemented.");
-    return 0;
+    // 64-bit object files have no auxiliary header.
+    return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0;
   }
 
 public:
@@ -468,6 +465,9 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
     const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(&S);
     const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym);
 
+    if (XSym->getVisibilityType() != XCOFF::SYM_V_UNSPECIFIED)
+      HasVisibility = true;
+
     if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) {
       // Handle undefined symbol.
       UndefinedCsects.emplace_back(ContainingCsect);
@@ -648,6 +648,7 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
   uint64_t StartOffset = W.OS.tell();
 
   writeFileHeader();
+  writeAuxFileHeader();
   writeSectionHeaderTable();
   writeSections(Asm, Layout);
   writeRelocations();
@@ -688,12 +689,6 @@ void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
     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
-  // is always zero.
-  if (SymbolType != 0)
-    report_fatal_error("Emitting non-zero visibilities is not supported yet.");
   // TODO Set the function indicator (bit 10, 0x0020) for functions
   // when debugging is enabled.
   W.write<uint16_t>(SymbolType);
@@ -773,18 +768,32 @@ void XCOFFObjectWriter::writeFileHeader() {
   W.write<int32_t>(0); // TimeStamp
   writeWord(SymbolTableOffset);
   if (is64Bit()) {
-    W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object
-                          // file that is not to be loaded.
+    W.write<uint16_t>(auxiliaryHeaderSize());
     W.write<uint16_t>(0); // Flags
     W.write<int32_t>(SymbolTableEntryCount);
   } else {
     W.write<int32_t>(SymbolTableEntryCount);
-    W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object
-                          // file that is not to be loaded.
+    W.write<uint16_t>(auxiliaryHeaderSize());
     W.write<uint16_t>(0); // Flags
   }
 }
 
+void XCOFFObjectWriter::writeAuxFileHeader() {
+  if (!auxiliaryHeaderSize())
+    return;
+  W.write<uint16_t>(0); // Magic
+  W.write<uint16_t>(
+      XCOFF::NEW_XCOFF_INTERPRET); // Version. The new interpretation of the
+                                   // n_type field in the symbol table entry is
+                                   // used in XCOFF32.
+  W.write<uint32_t>(Sections[0]->Size);    // TextSize
+  W.write<uint32_t>(Sections[1]->Size);    // InitDataSize
+  W.write<uint32_t>(Sections[2]->Size);    // BssDataSize
+  W.write<uint32_t>(0);                    // EntryPointAddr
+  W.write<uint32_t>(Sections[0]->Address); // TextStartAddr
+  W.write<uint32_t>(Sections[1]->Address); // DataStartAddr
+}
+
 void XCOFFObjectWriter::writeSectionHeaderTable() {
   auto writeSectionHeader = [&](const SectionEntry *Sec, bool IsDwarf) {
     // Nothing to write for this Section.

diff  --git a/llvm/test/CodeGen/PowerPC/aix-aux-header.ll b/llvm/test/CodeGen/PowerPC/aix-aux-header.ll
new file mode 100644
index 0000000000000..6ecef682ac790
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-aux-header.ll
@@ -0,0 +1,21 @@
+; RUN: llc -filetype=obj -mtriple=powerpc-ibm-aix-xcoff %s -o - | \
+; RUN:   llvm-readobj --auxiliary-header - | FileCheck %s
+
+; CHECK:      AuxiliaryHeader {
+; CHECK-NEXT:   Magic: 0x0
+; CHECK-NEXT:   Version: 0x2
+; CHECK-NEXT:   Size of .text section: 0x24
+; CHECK-NEXT:   Size of .data section: 0x14
+; CHECK-NEXT:   Size of .bss section: 0x0
+; CHECK-NEXT:   Entry point address: 0x0
+; CHECK-NEXT:   .text section start address: 0x0
+; CHECK-NEXT:   .data section start address: 0x24
+; CHECK-NEXT: }
+
+ at var = hidden global i32 0, align 4
+
+define hidden i32 @fun() {
+entry:
+  %0 = load i32, i32* @var, align 4
+  ret i32 %0
+}

diff  --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-visibility.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-visibility.ll
index 2b9afd3655d14..65c8d0f0751bb 100644
--- a/llvm/test/CodeGen/PowerPC/aix-xcoff-visibility.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-visibility.ll
@@ -3,15 +3,11 @@
 ; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 -mattr=-altivec -data-sections=false < %s |\
 ; RUN:   FileCheck %s
 
-; RUN: not --crash llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \
-; RUN:     -filetype=obj -o %t.o < %s 2>&1 | \
-; RUN:   FileCheck --check-prefix=XCOFF %s
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -filetype=obj %s -o %t.o
+; RUN: llvm-readobj --syms --auxiliary-header %t.o | FileCheck %s --check-prefixes=SYM,AUX32
 
-; RUN: not --crash llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:     -filetype=obj -o %t.o 2>&1 < %s 2>&1 | \
-; RUN:   FileCheck --check-prefix=XCOFF %s
-
-; XCOFF: LLVM ERROR: Emitting non-zero visibilities is not supported yet.
+; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -filetype=obj %s -o %t64.o
+; RUN: llvm-readobj --syms --auxiliary-header %t64.o | FileCheck %s --check-prefixes=SYM,AUX64
 
 @b =  global i32 0, align 4
 @b_h = hidden global i32 0, align 4
@@ -88,3 +84,155 @@ declare dllexport i32 @bar_e(i32*)
 ; CHECK:        .extern bar_h[DS],hidden
 ; CHECK:        .extern .bar_e[PR],exported
 ; CHECK:        .extern bar_e[DS],exported
+
+; AUX32:       AuxiliaryHeader {
+; AUX32-NEXT:    Magic: 0x0
+; AUX32-NEXT:    Version: 0x2
+; AUX32-NEXT:    Size of .text section: 0x134
+; AUX32-NEXT:    Size of .data section: 0x6C
+; AUX32-NEXT:    Size of .bss section: 0x0
+; AUX32-NEXT:    Entry point address: 0x0
+; AUX32-NEXT:    .text section start address: 0x0
+; AUX32-NEXT:    .data section start address: 0x134
+; AUX32-NEXT:  }
+
+; AUX64:       AuxiliaryHeader {
+; AUX64-NEXT:  }
+
+; SYM:         Name: .bar_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: zoo_weak_extern_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: .zoo_weak_extern_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: .zoo_weak_extern_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: zoo_weak_extern_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: bar_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .bar_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: bar_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: N_UNDEF
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .foo
+; SYM-NEXT:    Value (RelocatableAddress): 0x0
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x0
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .foo_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x1C
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .foo_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x3C
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .foo_protected
+; SYM-NEXT:    Value (RelocatableAddress): 0x5C
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x3000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: .foo_weak_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x84
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: .foo_weak_e
+; SYM-NEXT:    Value (RelocatableAddress): 0xA4
+; SYM-NEXT:    Section: .text
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: b
+; SYM-NEXT:    Value (RelocatableAddress): 0x134
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x0
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: b_h
+; SYM-NEXT:    Value (RelocatableAddress): 0x138
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: b_e
+; SYM-NEXT:    Value (RelocatableAddress): 0x13C
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: foo
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x0
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: foo_h
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: foo_e
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: foo_protected
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x3000
+; SYM-NEXT:    StorageClass: C_EXT (0x2)
+
+; SYM:         Name: foo_weak_h
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x2000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)
+
+; SYM:         Name: foo_weak_e
+; SYM-NEXT:    Value (RelocatableAddress): {{[0-9]+}}
+; SYM-NEXT:    Section: .data
+; SYM-NEXT:    Type: 0x4000
+; SYM-NEXT:    StorageClass: C_WEAKEXT (0x6F)


        


More information about the llvm-commits mailing list