diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h --- a/llvm/include/llvm/BinaryFormat/XCOFF.h +++ b/llvm/include/llvm/BinaryFormat/XCOFF.h @@ -31,6 +31,7 @@ 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 --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -201,6 +201,7 @@ uint16_t SectionCount = 0; uint64_t RelocationEntryOffset = 0; StringRef SourceFileName = ".file"; + bool HasVisibility = false; support::endian::Writer W; std::unique_ptr TargetObjectWriter; @@ -270,6 +271,7 @@ 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, @@ -303,14 +305,8 @@ 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; + return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0; } public: @@ -463,6 +459,9 @@ const MCSymbolXCOFF *XSym = cast(&S); const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym); + if (XSym->getVisibilityType()) + HasVisibility = true; + if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) { // Handle undefined symbol. UndefinedCsects.emplace_back(ContainingCsect); @@ -638,6 +637,7 @@ uint64_t StartOffset = W.OS.tell(); writeFileHeader(); + writeAuxFileHeader(); writeSectionHeaderTable(); writeSections(Asm, Layout); writeRelocations(); @@ -678,12 +678,6 @@ W.write(Value); } W.write(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(SymbolType); @@ -763,18 +757,32 @@ W.write(0); // TimeStamp writeWord(SymbolTableOffset); if (is64Bit()) { - W.write(0); // AuxHeaderSize. No optional header for an object - // file that is not to be loaded. + W.write(0); // AuxHeaderSize. W.write(0); // Flags W.write(SymbolTableEntryCount); } else { W.write(SymbolTableEntryCount); - W.write(0); // AuxHeaderSize. No optional header for an object - // file that is not to be loaded. + W.write(auxiliaryHeaderSize()); W.write(0); // Flags } } +void XCOFFObjectWriter::writeAuxFileHeader() { + if (!auxiliaryHeaderSize()) + return; + W.write(0); // Magic + W.write( + XCOFF::NEW_XCOFF_INTERPRET); // Version. The new interpretation of the + // n_type field in the symbol table entry is + // used in XCOFF32. + W.write(0); // TextSize + W.write(0); // InitDataSize + W.write(0); // BssDataSize + W.write(0); // EntryPointAddr + W.write(0); // TextStartAddr + W.write(0); // 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 --- /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: 0x0 +; CHECK-NEXT: Size of .data section: 0x0 +; 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: 0x0 +; CHECK-NEXT: } + +@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 --- 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=XCOFF,XCOFF32 -; 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=XCOFF,XCOFF64 @b = global i32 0, align 4 @b_h = hidden global i32 0, align 4 @@ -88,3 +84,155 @@ ; CHECK: .extern bar_h[DS],hidden ; CHECK: .extern .bar_e[PR],exported ; CHECK: .extern bar_e[DS],exported + +; XCOFF32: AuxiliaryHeader { +; XCOFF32-NEXT: Magic: 0x0 +; XCOFF32-NEXT: Version: 0x2 +; XCOFF32-NEXT: Size of .text section: 0x0 +; XCOFF32-NEXT: Size of .data section: 0x0 +; XCOFF32-NEXT: Size of .bss section: 0x0 +; XCOFF32-NEXT: Entry point address: 0x0 +; XCOFF32-NEXT: .text section start address: 0x0 +; XCOFF32-NEXT: .data section start address: 0x0 +; XCOFF32-NEXT: } + +; XCOFF64: AuxiliaryHeader { +; XCOFF64-NEXT: } + +; XCOFF: Name: .bar_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: zoo_weak_extern_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: .zoo_weak_extern_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: .zoo_weak_extern_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: zoo_weak_extern_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: bar_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .bar_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: bar_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: N_UNDEF +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .foo +; XCOFF-NEXT: Value (RelocatableAddress): 0x0 +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x0 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .foo_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x1C +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .foo_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x3C +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .foo_protected +; XCOFF-NEXT: Value (RelocatableAddress): 0x5C +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x3000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: .foo_weak_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x84 +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: .foo_weak_e +; XCOFF-NEXT: Value (RelocatableAddress): 0xA4 +; XCOFF-NEXT: Section: .text +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: b +; XCOFF-NEXT: Value (RelocatableAddress): 0x134 +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x0 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: b_h +; XCOFF-NEXT: Value (RelocatableAddress): 0x138 +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: b_e +; XCOFF-NEXT: Value (RelocatableAddress): 0x13C +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: foo +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x0 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: foo_h +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: foo_e +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: foo_protected +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x3000 +; XCOFF-NEXT: StorageClass: C_EXT (0x2) + +; XCOFF: Name: foo_weak_h +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x2000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F) + +; XCOFF: Name: foo_weak_e +; XCOFF-NEXT: Value (RelocatableAddress): {{[0-9]+}} +; XCOFF-NEXT: Section: .data +; XCOFF-NEXT: Type: 0x4000 +; XCOFF-NEXT: StorageClass: C_WEAKEXT (0x6F)