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:      ]