Index: llvm/lib/MC/XCOFFObjectWriter.cpp =================================================================== --- llvm/lib/MC/XCOFFObjectWriter.cpp +++ llvm/lib/MC/XCOFFObjectWriter.cpp @@ -127,12 +127,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; @@ -191,6 +193,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() { @@ -201,6 +204,7 @@ // Clear any csects we have stored. ProgramCodeCsects.clear(); + DataCsects.clear(); BSSCsects.clear(); // Reset the symbol table and string table. @@ -244,6 +248,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. @@ -295,6 +304,10 @@ // Write the program code control sections one at a time. for (const auto CSection : ProgramCodeCsects) Asm.writeSectionData(W.OS, CSection.MCCsect, Layout); + + // Write the data csects one at a time. + for (const auto CSection : DataCsects) + Asm.writeSectionData(W.OS, CSection.MCCsect, Layout); } uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, @@ -459,6 +472,17 @@ } } + // Print out symbol table for the data section. + for (const auto CSection : DataCsects) { + // Write out the control section first and then each symbol in it. + writeSymbolTableEntryForControlSection(CSection, Data.Index, + CSection.MCCsect->getStorageClass()); + for (const auto Sym : CSection.Syms) { + writeSymbolTableEntryForSymbol(Sym, CSection, 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. @@ -475,7 +499,7 @@ // The address corrresponds to the address of sections and symbols in the // object file. We place the shared address 0 immediately after the // section header table. - uint32_t Address = 0; + uint32_t SectionStartAddress = 0; // Section indices are 1-based in XCOFF. uint16_t SectionIndex = 1; // The first symbol table entry is for the file name. We are not emitting it @@ -486,7 +510,7 @@ if (!ProgramCodeCsects.empty()) { Sections.push_back(&Text); Text.Index = SectionIndex++; - uint32_t StartAddress = Address; + uint32_t Address = SectionStartAddress; for (auto &Csect : ProgramCodeCsects) { const MCSectionXCOFF *MCSec = Csect.MCCsect; Address = alignTo(Address, MCSec->getAlignment()); @@ -504,16 +528,43 @@ } assert(alignTo(Address, DefaultSectionAlign) == Address && "Improperly aligned address for section."); - Text.Size = Address - StartAddress; + Text.Size = Address - SectionStartAddress; + SectionStartAddress = Address; } - // Data section Second. TODO + // Data section second. + if (!DataCsects.empty()) { + Sections.push_back(&Data); + Data.Index = SectionIndex++; + Data.Address = SectionStartAddress; + uint32_t Address = SectionStartAddress; + for (auto &Csect : DataCsects) { + const MCSectionXCOFF *MCSec = Csect.MCCsect; + Address = alignTo(Address, MCSec->getAlignment()); + 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 aligned to DefaultSectionAlign. + Address = alignTo(Address, DefaultSectionAlign); + Data.Size = Address - SectionStartAddress; + SectionStartAddress = Address; + } // BSS Section third. if (!BSSCsects.empty()) { Sections.push_back(&BSS); BSS.Index = SectionIndex++; - uint32_t StartAddress = Address; + BSS.Address = SectionStartAddress; + uint32_t Address = SectionStartAddress; for (auto &Csect : BSSCsects) { const MCSectionXCOFF *MCSec = Csect.MCCsect; Address = alignTo(Address, MCSec->getAlignment()); @@ -531,7 +582,8 @@ // Pad out Address to the default alignment. This is to match how the system // assembler handles the .bss section. Its size is always a multiple of 4. Address = alignTo(Address, DefaultSectionAlign); - BSS.Size = Address - StartAddress; + BSS.Size = Address - SectionStartAddress; + SectionStartAddress = Address; } SymbolTableEntryCount = SymbolTableIndex; 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,6 +1,14 @@ ; 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 %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 @@ -55,3 +63,220 @@ ; CHECK-NEXT: .llong 4611686018427387904 ; CHECK-NEXT: .llong 4613937818241073152 ; CHECK-NEXT: .llong 4616189618054758400 + +; OBJ: File: {{.*}}aix-xcoff-data.ll.tmp.o +; OBJ-NEXT: Format: aixcoff-rs6000 +; OBJ-NEXT: Arch: powerpc +; OBJ-NEXT: AddressSize: 32bit + +; 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: charr +; 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: ]