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 @@ -206,6 +206,7 @@ uint16_t SectionCount = 0; uint64_t RelocationEntryOffset = 0; std::vector> FileNames; + bool HasVisibility = false; support::endian::Writer W; std::unique_ptr TargetObjectWriter; @@ -275,6 +276,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, @@ -308,14 +310,9 @@ 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. + // 64-bit object files have no auxiliary header. size_t auxiliaryHeaderSize() const { - assert(!needsAuxiliaryHeader() && - "Auxiliary header support not implemented."); - return 0; + return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0; } public: @@ -468,6 +465,9 @@ const MCSymbolXCOFF *XSym = cast(&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 StartOffset = W.OS.tell(); writeFileHeader(); + writeAuxFileHeader(); writeSectionHeaderTable(); writeSections(Asm, Layout); writeRelocations(); @@ -688,12 +689,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); @@ -773,18 +768,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(auxiliaryHeaderSize()); 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(Sections[0]->Size); // TextSize + W.write(Sections[1]->Size); // InitDataSize + W.write(Sections[2]->Size); // BssDataSize + W.write(0); // EntryPointAddr + W.write(Sections[0]->Address); // TextStartAddr + W.write(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 --- /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: } + +@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=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 @@ ; 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)