Index: llvm/lib/MC/XCOFFObjectWriter.cpp =================================================================== --- llvm/lib/MC/XCOFFObjectWriter.cpp +++ llvm/lib/MC/XCOFFObjectWriter.cpp @@ -132,12 +132,14 @@ // The Predefined sections. Section Text; + Section Data; Section BSS; // ControlSections. These store the csects which make up different parts of // the sections. Should have one for each set of csects that get mapped into // the same section and get handled in a 'similar' way. ControlSections ProgramCodeCsects; + ControlSections DataCsects; ControlSections BSSCsects; uint32_t SymbolTableEntryCount = 0; @@ -196,6 +198,7 @@ : W(OS, support::big), TargetObjectWriter(std::move(MOTW)), Strings(StringTableBuilder::XCOFF), Text(".text", XCOFF::STYP_TEXT, /* IsVirtual */ false), + Data(".data", XCOFF::STYP_DATA, /* IsVirtual */ false), BSS(".bss", XCOFF::STYP_BSS, /* IsVirtual */ true) {} void XCOFFObjectWriter::reset() { @@ -206,6 +209,7 @@ // Clear any csects we have stored. ProgramCodeCsects.clear(); + DataCsects.clear(); BSSCsects.clear(); // Reset the symbol table and string table. @@ -249,6 +253,11 @@ WrapperMap[MCSec] = &BSSCsects.back(); break; } + if (XCOFF::XTY_SD == MCSec->getCSectType()) { + DataCsects.emplace_back(MCSec); + WrapperMap[MCSec] = &DataCsects.back(); + break; + } report_fatal_error("Unhandled mapping of read-write csect to section."); case XCOFF::XMC_TC0: // TODO FIXME Handle emiting the TOC base. @@ -306,6 +315,16 @@ if (ProgramCodeCsects.size() && Text.PaddingSize) W.OS.write_zeros(Text.PaddingSize); + + // Write the data csects one at a time. + for (const auto &Csect : DataCsects) { + if (Csect.PaddingSize) + W.OS.write_zeros(Csect.PaddingSize); + Asm.writeSectionData(W.OS, Csect.MCCsect, Layout); + } + + if (DataCsects.size() && Data.PaddingSize) + W.OS.write_zeros(Data.PaddingSize); } uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, @@ -479,6 +498,17 @@ } } + // Print out symbol table for the data section. + for (const auto &Csect : DataCsects) { + // Write out the control section first and then each symbol in it. + writeSymbolTableEntryForControlSection(Csect, Data.Index, + Csect.MCCsect->getStorageClass()); + for (const auto &Sym : Csect.Syms) { + writeSymbolTableEntryForCsectMemberLabel( + Sym, Csect, Data.Index, Layout.getSymbolOffset(*(Sym.MCSym))); + } + } + // The BSS Section is special in that the csects must contain a single symbol, // and the contained symbol cannot be represented in the symbol table as a // label definition. @@ -528,7 +558,33 @@ Text.Size = Address - Text.Address; } - // Data section Second. TODO + // Data section second. + if (!DataCsects.empty()) { + Sections.push_back(&Data); + Data.Index = SectionIndex++; + Data.Address = Address; + for (auto &Csect : DataCsects) { + const MCSectionXCOFF *MCSec = Csect.MCCsect; + Csect.PaddingSize = alignTo(Address, MCSec->getAlignment()) - Address; + Address += Csect.PaddingSize; + Csect.Address = Address; + Address += Layout.getSectionAddressSize(MCSec); + Csect.SymbolTableIndex = SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for the csect. + SymbolTableIndex += 2; + Csect.Size = Layout.getSectionAddressSize(MCSec); + for (auto &Sym : Csect.Syms) { + Sym.SymbolTableIndex = SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for each contained symbol. + SymbolTableIndex += 2; + } + } + // Make sure the address of the next section will be aligned to + // DefaultSectionAlign. + Data.PaddingSize = alignTo(Address, DefaultSectionAlign) - Address; + Address += Data.PaddingSize; + Data.Size = Address - Data.Address; + } // BSS Section third. if (!BSSCsects.empty()) { Index: llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll =================================================================== --- llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll +++ llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll @@ -1,15 +1,27 @@ ; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s ; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --symbols --section-headers %t.o | \ +; RUN: FileCheck --check-prefix=OBJ %s + +; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj < %s 2>&1 | \ +; RUN: FileCheck --check-prefix=XCOFF64 %s +; XCOFF64: LLVM ERROR: 64-bit XCOFF object files are not supported yet. + @ivar = local_unnamed_addr global i32 35, align 4 @llvar = local_unnamed_addr global i64 36, align 8 @svar = local_unnamed_addr global i16 37, align 2 @fvar = local_unnamed_addr global float 8.000000e+02, align 4 @dvar = local_unnamed_addr global double 9.000000e+02, align 8 @over_aligned = local_unnamed_addr global double 9.000000e+02, align 32 -@charr = local_unnamed_addr global [4 x i8] c"abcd", align 1 +@chrarray = local_unnamed_addr global [4 x i8] c"abcd", align 1 @dblarr = local_unnamed_addr global [4 x double] [double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00], align 8 +@a = common global i32 0, align 4 +@b = common global i64 0, align 8 +@c = common global i16 0, align 2 + ; CHECK: .csect .data[RW] ; CHECK-NEXT: .globl ivar ; CHECK-NEXT: .align 2 @@ -41,8 +53,8 @@ ; CHECK-NEXT: over_aligned: ; CHECK-NEXT: .llong 4651127699538968576 -; CHECK: .globl charr -; CHECK-NEXT: charr: +; CHECK: .globl chrarray +; CHECK-NEXT: chrarray: ; CHECK-NEXT: .byte 97 ; CHECK-NEXT: .byte 98 ; CHECK-NEXT: .byte 99 @@ -55,3 +67,268 @@ ; CHECK-NEXT: .llong 4611686018427387904 ; CHECK-NEXT: .llong 4613937818241073152 ; CHECK-NEXT: .llong 4616189618054758400 + +; CHECK: .comm a,4,2 +; CHECK-NEXT: .comm b,8,3 +; CHECK-NEXT: .comm c,2,1 + +; OBJ: File: {{.*}}aix-xcoff-data.ll.tmp.o +; OBJ-NEXT: Format: aixcoff-rs6000 +; OBJ-NEXT: Arch: powerpc +; OBJ-NEXT: AddressSize: 32bit + +; OBJ: Sections [ +; OBJ: Section { +; OBJ-NEXT: Index: 1 +; OBJ-NEXT: Name: .text +; OBJ-NEXT: PhysicalAddress: 0x0 +; OBJ-NEXT: VirtualAddress: 0x0 +; OBJ-NEXT: Size: 0x0 +; OBJ-NEXT: RawDataOffset: 0x8C +; OBJ-NEXT: RelocationPointer: 0x0 +; OBJ-NEXT: LineNumberPointer: 0x0 +; OBJ-NEXT: NumberOfRelocations: 0 +; OBJ-NEXT: NumberOfLineNumbers: 0 +; OBJ-NEXT: Type: STYP_TEXT (0x20) +; OBJ-NEXT: } + +; OBJ: Section { +; OBJ-NEXT: Index: 2 +; OBJ-NEXT: Name: .data +; OBJ-NEXT: PhysicalAddress: 0x0 +; OBJ-NEXT: VirtualAddress: 0x0 +; OBJ-NEXT: Size: 0x50 +; OBJ-NEXT: RawDataOffset: 0x8C +; OBJ-NEXT: RelocationPointer: 0x0 +; OBJ-NEXT: LineNumberPointer: 0x0 +; OBJ-NEXT: NumberOfRelocations: 0 +; OBJ-NEXT: NumberOfLineNumbers: 0 +; OBJ-NEXT: Type: STYP_DATA (0x40) +; OBJ-NEXT: } + +; OBJ: Section { +; OBJ-NEXT: Index: 3 +; OBJ-NEXT: Name: .bss +; OBJ-NEXT: PhysicalAddress: 0x50 +; OBJ-NEXT: VirtualAddress: 0x50 +; OBJ-NEXT: Size: 0x14 +; OBJ-NEXT: RawDataOffset: 0x0 +; OBJ-NEXT: RelocationPointer: 0x0 +; OBJ-NEXT: LineNumberPointer: 0x0 +; OBJ-NEXT: NumberOfRelocations: 0 +; OBJ-NEXT: NumberOfLineNumbers: 0 +; OBJ-NEXT: Type: STYP_BSS (0x80) +; OBJ-NEXT: } +; OBJ: ] + +; OBJ: Symbols [ +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX:]] +; OBJ-NEXT: Name: .text +; OBJ-NEXT: Value (RelocatableAddress): 0x0 +; OBJ-NEXT: Section: .text +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_HIDEXT (0x6B) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+1]] +; OBJ-NEXT: SectionLen: 0 +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_SD (0x1) +; OBJ-NEXT: StorageMappingClass: XMC_PR (0x0) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+2]] +; OBJ-NEXT: Name: .data +; OBJ-NEXT: Value (RelocatableAddress): 0x0 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_HIDEXT (0x6B) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+3]] +; OBJ-NEXT: SectionLen: 80 +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 5 +; OBJ-NEXT: SymbolType: XTY_SD (0x1) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+4]] +; OBJ-NEXT: Name: ivar +; OBJ-NEXT: Value (RelocatableAddress): 0x0 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+5]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+6]] +; OBJ-NEXT: Name: llvar +; OBJ-NEXT: Value (RelocatableAddress): 0x8 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+7]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+8]] +; OBJ-NEXT: Name: svar +; OBJ-NEXT: Value (RelocatableAddress): 0x10 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+9]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+10]] +; OBJ-NEXT: Name: fvar +; OBJ-NEXT: Value (RelocatableAddress): 0x14 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+11]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+12]] +; OBJ-NEXT: Name: dvar +; OBJ-NEXT: Value (RelocatableAddress): 0x18 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+13]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+14]] +; OBJ-NEXT: Name: over_aligned +; OBJ-NEXT: Value (RelocatableAddress): 0x20 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+15]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+16]] +; OBJ-NEXT: Name: chrarray +; OBJ-NEXT: Value (RelocatableAddress): 0x28 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+17]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } + +; OBJ: Symbol { +; OBJ-NEXT: Index: [[#INDX+18]] +; OBJ-NEXT: Name: dblarr +; OBJ-NEXT: Value (RelocatableAddress): 0x30 +; OBJ-NEXT: Section: .data +; OBJ-NEXT: Type: 0x0 +; OBJ-NEXT: StorageClass: C_EXT (0x2) +; OBJ-NEXT: NumberOfAuxEntries: 1 +; OBJ-NEXT: CSECT Auxiliary Entry { +; OBJ-NEXT: Index: [[#INDX+19]] +; OBJ-NEXT: ContainingCsectSymbolIndex: [[#INDX+2]] +; OBJ-NEXT: ParameterHashIndex: 0x0 +; OBJ-NEXT: TypeChkSectNum: 0x0 +; OBJ-NEXT: SymbolAlignmentLog2: 0 +; OBJ-NEXT: SymbolType: XTY_LD (0x2) +; OBJ-NEXT: StorageMappingClass: XMC_RW (0x5) +; OBJ-NEXT: StabInfoIndex: 0x0 +; OBJ-NEXT: StabSectNum: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: } +; OBJ: ]