[llvm] r217812 - MC: Add support for BigObj

David Majnemer david.majnemer at gmail.com
Mon Sep 15 12:42:43 PDT 2014


Author: majnemer
Date: Mon Sep 15 14:42:42 2014
New Revision: 217812

URL: http://llvm.org/viewvc/llvm-project?rev=217812&view=rev
Log:
MC: Add support for BigObj

Teach WinCOFFObjectWriter how to write -mbig-obj style object files;
these object files allow for more sections inside an object file.

Our support for BigObj is notably different from binutils and cl: we
implicitly upgrade object files to BigObj instead of asking the user to
compile the same file *again* but with another flag.  This matches up
with how LLVM treats ELF variants.

This was tested by forcing LLVM to always emit BigObj files and running
the entire test suite.  A specific test has also been added.

I've lowered the maximum number of sections in a normal COFF file,
VS "14" CTP 3 supports no more than 65279 sections.  This is important
otherwise we might not switch to BigObj quickly enough, leaving us with
a COFF file that we couldn't link.

yaml2obj support is all that remains to implement.

Differential Revision: http://reviews.llvm.org/D5349

Modified:
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/include/llvm/Support/COFF.h
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/tools/obj2yaml/coff2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2coff.cpp

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Mon Sep 15 14:42:42 2014
@@ -236,6 +236,14 @@ public:
     return A.getRawPtr() < B.getRawPtr();
   }
 
+  bool isBigObj() const {
+    if (CS16)
+      return false;
+    if (CS32)
+      return true;
+    llvm_unreachable("COFFSymbolRef points to nothing!");
+  }
+
   const char *getShortName() const {
     return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
   }
@@ -361,8 +369,16 @@ struct coff_aux_section_definition {
   support::ulittle16_t NumberOfRelocations;
   support::ulittle16_t NumberOfLinenumbers;
   support::ulittle32_t CheckSum;
-  support::ulittle16_t Number;
+  support::ulittle16_t NumberLowPart;
   uint8_t              Selection;
+  uint8_t              Unused;
+  support::ulittle16_t NumberHighPart;
+  int32_t getNumber(bool IsBigObj) const {
+    uint32_t Number = static_cast<uint32_t>(NumberLowPart);
+    if (IsBigObj)
+      Number |= static_cast<uint32_t>(NumberHighPart) << 16;
+    return static_cast<int32_t>(Number);
+  }
 };
 
 struct coff_aux_clr_token {

Modified: llvm/trunk/include/llvm/Support/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/COFF.h?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/COFF.h (original)
+++ llvm/trunk/include/llvm/Support/COFF.h Mon Sep 15 14:42:42 2014
@@ -31,7 +31,7 @@ namespace llvm {
 namespace COFF {
 
   // The maximum number of sections that a COFF object can have (inclusive).
-  const uint16_t MaxNumberOfSections16 = 65299;
+  const int32_t MaxNumberOfSections16 = 65279;
 
   // The PE signature bytes that follows the DOS stub header.
   static const char PEMagic[] = { 'P', 'E', '\0', '\0' };
@@ -43,16 +43,18 @@ namespace COFF {
 
   // Sizes in bytes of various things in the COFF format.
   enum {
-    HeaderSize     = 20,
+    Header16Size   = 20,
+    Header32Size   = 56,
     NameSize       = 8,
-    SymbolSize     = 18,
+    Symbol16Size   = 18,
+    Symbol32Size   = 20,
     SectionSize    = 40,
     RelocationSize = 10
   };
 
   struct header {
     uint16_t Machine;
-    uint16_t NumberOfSections;
+    int32_t  NumberOfSections;
     uint32_t TimeDateStamp;
     uint32_t PointerToSymbolTable;
     uint32_t NumberOfSymbols;
@@ -147,7 +149,7 @@ namespace COFF {
   struct symbol {
     char     Name[NameSize];
     uint32_t Value;
-    uint16_t SectionNumber;
+    int32_t  SectionNumber;
     uint16_t Type;
     uint8_t  StorageClass;
     uint8_t  NumberOfAuxSymbols;
@@ -390,18 +392,14 @@ namespace COFF {
     IMAGE_WEAK_EXTERN_SEARCH_ALIAS     = 3
   };
 
-  struct AuxiliaryFile {
-    uint8_t FileName[18];
-  };
-
   struct AuxiliarySectionDefinition {
     uint32_t Length;
     uint16_t NumberOfRelocations;
     uint16_t NumberOfLinenumbers;
     uint32_t CheckSum;
-    uint16_t Number;
+    uint32_t Number;
     uint8_t  Selection;
-    char     unused[3];
+    char     unused;
   };
 
   struct AuxiliaryCLRToken {
@@ -415,7 +413,6 @@ namespace COFF {
     AuxiliaryFunctionDefinition FunctionDefinition;
     AuxiliarybfAndefSymbol      bfAndefSymbol;
     AuxiliaryWeakExternal       WeakExternal;
-    AuxiliaryFile               File;
     AuxiliarySectionDefinition  SectionDefinition;
   };
 

Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Mon Sep 15 14:42:42 2014
@@ -71,7 +71,6 @@ public:
   MCSymbolData const *MCData;
 
   COFFSymbol(StringRef name);
-  size_t size() const;
   void set_name_offset(uint32_t Offset);
 
   bool should_keep() const;
@@ -137,6 +136,8 @@ public:
   section_map SectionMap;
   symbol_map  SymbolMap;
 
+  bool UseBigObj;
+
   WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS);
 
   COFFSymbol *createSymbol(StringRef Name);
@@ -199,10 +200,6 @@ COFFSymbol::COFFSymbol(StringRef name)
   memset(&Data, 0, sizeof(Data));
 }
 
-size_t COFFSymbol::size() const {
-  return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize);
-}
-
 // In the case that the name does not fit within 8 bytes, the offset
 // into the string table is stored in the last 4 bytes instead, leaving
 // the first 4 bytes as 0.
@@ -301,8 +298,7 @@ size_t StringTable::insert(StringRef Str
 
 WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
                                          raw_ostream &OS)
-  : MCObjectWriter(OS, true)
-  , TargetObjectWriter(MOTW) {
+    : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) {
   memset(&Header, 0, sizeof(Header));
 
   Header.Machine = TargetObjectWriter->getMachine();
@@ -578,19 +574,39 @@ bool WinCOFFObjectWriter::IsPhysicalSect
 // entity writing methods
 
 void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
-  WriteLE16(Header.Machine);
-  WriteLE16(Header.NumberOfSections);
-  WriteLE32(Header.TimeDateStamp);
-  WriteLE32(Header.PointerToSymbolTable);
-  WriteLE32(Header.NumberOfSymbols);
-  WriteLE16(Header.SizeOfOptionalHeader);
-  WriteLE16(Header.Characteristics);
+  if (UseBigObj) {
+    WriteLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
+    WriteLE16(0xFFFF);
+    WriteLE16(COFF::BigObjHeader::MinBigObjectVersion);
+    WriteLE16(Header.Machine);
+    WriteLE32(Header.TimeDateStamp);
+    for (uint8_t MagicChar : COFF::BigObjMagic)
+      Write8(MagicChar);
+    WriteZeros(sizeof(COFF::BigObjHeader::unused1));
+    WriteZeros(sizeof(COFF::BigObjHeader::unused2));
+    WriteZeros(sizeof(COFF::BigObjHeader::unused3));
+    WriteZeros(sizeof(COFF::BigObjHeader::unused4));
+    WriteLE32(Header.NumberOfSections);
+    WriteLE32(Header.PointerToSymbolTable);
+    WriteLE32(Header.NumberOfSymbols);
+  } else {
+    WriteLE16(Header.Machine);
+    WriteLE16(static_cast<int16_t>(Header.NumberOfSections));
+    WriteLE32(Header.TimeDateStamp);
+    WriteLE32(Header.PointerToSymbolTable);
+    WriteLE32(Header.NumberOfSymbols);
+    WriteLE16(Header.SizeOfOptionalHeader);
+    WriteLE16(Header.Characteristics);
+  }
 }
 
 void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
   WriteBytes(StringRef(S.Data.Name, COFF::NameSize));
   WriteLE32(S.Data.Value);
-  WriteLE16(S.Data.SectionNumber);
+  if (UseBigObj)
+    WriteLE32(S.Data.SectionNumber);
+  else
+    WriteLE16(static_cast<int16_t>(S.Data.SectionNumber));
   WriteLE16(S.Data.Type);
   Write8(S.Data.StorageClass);
   Write8(S.Data.NumberOfAuxSymbols);
@@ -608,6 +624,8 @@ void WinCOFFObjectWriter::WriteAuxiliary
       WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber);
       WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction);
       WriteZeros(sizeof(i->Aux.FunctionDefinition.unused));
+      if (UseBigObj)
+        WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
       break;
     case ATbfAndefSymbol:
       WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1));
@@ -615,24 +633,32 @@ void WinCOFFObjectWriter::WriteAuxiliary
       WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2));
       WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction);
       WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3));
+      if (UseBigObj)
+        WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
       break;
     case ATWeakExternal:
       WriteLE32(i->Aux.WeakExternal.TagIndex);
       WriteLE32(i->Aux.WeakExternal.Characteristics);
       WriteZeros(sizeof(i->Aux.WeakExternal.unused));
+      if (UseBigObj)
+        WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
       break;
     case ATFile:
-      WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName),
-                 sizeof(i->Aux.File.FileName)));
+      WriteBytes(
+          StringRef(reinterpret_cast<const char *>(&i->Aux),
+                    UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
       break;
     case ATSectionDefinition:
       WriteLE32(i->Aux.SectionDefinition.Length);
       WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations);
       WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers);
       WriteLE32(i->Aux.SectionDefinition.CheckSum);
-      WriteLE16(i->Aux.SectionDefinition.Number);
+      WriteLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number));
       Write8(i->Aux.SectionDefinition.Selection);
       WriteZeros(sizeof(i->Aux.SectionDefinition.unused));
+      WriteLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number >> 16));
+      if (UseBigObj)
+        WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
       break;
     }
   }
@@ -665,37 +691,6 @@ void WinCOFFObjectWriter::ExecutePostLay
                                                    const MCAsmLayout &Layout) {
   // "Define" each section & symbol. This creates section & symbol
   // entries in the staging area.
-
-  static_assert(sizeof(((COFF::AuxiliaryFile *)nullptr)->FileName) == COFF::SymbolSize,
-                "size mismatch for COFF::AuxiliaryFile::FileName");
-  for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end();
-       FI != FE; ++FI) {
-    // round up to calculate the number of auxiliary symbols required
-    unsigned Count = (FI->size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
-
-    COFFSymbol *file = createSymbol(".file");
-    file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
-    file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
-    file->Aux.resize(Count);
-
-    unsigned Offset = 0;
-    unsigned Length = FI->size();
-    for (auto & Aux : file->Aux) {
-      Aux.AuxType = ATFile;
-
-      if (Length > COFF::SymbolSize) {
-        memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, COFF::SymbolSize);
-        Length = Length - COFF::SymbolSize;
-      } else {
-        memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, Length);
-        memset(&Aux.Aux.File.FileName[Length], 0, COFF::SymbolSize - Length);
-        Length = 0;
-      }
-
-      Offset = Offset + COFF::SymbolSize;
-    }
-  }
-
   for (const auto & Section : Asm)
     DefineSection(Section);
 
@@ -839,23 +834,57 @@ void WinCOFFObjectWriter::RecordRelocati
 
 void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
                                       const MCAsmLayout &Layout) {
+  size_t SectionsSize = Sections.size();
+  if (SectionsSize > static_cast<size_t>(INT32_MAX))
+    report_fatal_error(
+        "PE COFF object files can't have more than 2147483647 sections");
+
   // Assign symbol and section indexes and offsets.
-  size_t NumberOfSections = 0;
+  int32_t NumberOfSections = static_cast<int32_t>(SectionsSize);
+
+  UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16;
 
-  DenseMap<COFFSection *, uint16_t> SectionIndices;
+  DenseMap<COFFSection *, int32_t> SectionIndices(
+      NextPowerOf2(NumberOfSections));
+  size_t Number = 1;
   for (const auto &Section : Sections) {
-    size_t Number = ++NumberOfSections;
-    SectionIndices[Section.get()] = static_cast<uint16_t>(Number);
+    SectionIndices[Section.get()] = Number;
     MakeSectionReal(*Section, Number);
+    ++Number;
   }
 
-  if (NumberOfSections > static_cast<size_t>(COFF::MaxNumberOfSections16))
-    report_fatal_error(
-        "PE COFF object files can't have more than 65,299 sections");
-
-  Header.NumberOfSections = static_cast<uint16_t>(NumberOfSections);
+  Header.NumberOfSections = NumberOfSections;
   Header.NumberOfSymbols = 0;
 
+  for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end();
+       FI != FE; ++FI) {
+    // round up to calculate the number of auxiliary symbols required
+    unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
+    unsigned Count = (FI->size() + SymbolSize - 1) / SymbolSize;
+
+    COFFSymbol *file = createSymbol(".file");
+    file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
+    file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
+    file->Aux.resize(Count);
+
+    unsigned Offset = 0;
+    unsigned Length = FI->size();
+    for (auto & Aux : file->Aux) {
+      Aux.AuxType = ATFile;
+
+      if (Length > SymbolSize) {
+        memcpy(&Aux.Aux, FI->c_str() + Offset, SymbolSize);
+        Length = Length - SymbolSize;
+      } else {
+        memcpy(&Aux.Aux, FI->c_str() + Offset, Length);
+        memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
+        break;
+      }
+
+      Offset += SymbolSize;
+    }
+  }
+
   for (auto &Symbol : Symbols) {
     // Update section number & offset for symbols that have them.
     if (Symbol->Section)
@@ -913,7 +942,10 @@ void WinCOFFObjectWriter::WriteObject(MC
 
   unsigned offset = 0;
 
-  offset += COFF::HeaderSize;
+  if (UseBigObj)
+    offset += COFF::Header32Size;
+  else
+    offset += COFF::Header16Size;
   offset += COFF::SectionSize * Header.NumberOfSections;
 
   for (const auto & Section : Asm) {

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Mon Sep 15 14:42:42 2014
@@ -591,6 +591,8 @@ static void PrintCOFFSymbolTable(const C
         if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd)))
           return;
 
+        int32_t AuxNumber = asd->getNumber(Symbol->isBigObj());
+
         outs() << "AUX "
                << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
                          , unsigned(asd->Length)
@@ -598,7 +600,7 @@ static void PrintCOFFSymbolTable(const C
                          , unsigned(asd->NumberOfLinenumbers)
                          , unsigned(asd->CheckSum))
                << format("assoc %d comdat %d\n"
-                         , unsigned(asd->Number)
+                         , unsigned(AuxNumber)
                          , unsigned(asd->Selection));
       } else if (Symbol->isFileRecord()) {
         const char *FileName;

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Mon Sep 15 14:42:42 2014
@@ -790,12 +790,14 @@ void COFFDumper::printSymbol(const Symbo
       if (error(getSymbolAuxData(Obj, Symbol, I, Aux)))
         break;
 
+      int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj());
+
       DictScope AS(W, "AuxSectionDef");
       W.printNumber("Length", Aux->Length);
       W.printNumber("RelocationCount", Aux->NumberOfRelocations);
       W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
       W.printHex("Checksum", Aux->CheckSum);
-      W.printNumber("Number", Aux->Number);
+      W.printNumber("Number", AuxNumber);
       W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
 
       if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
@@ -803,13 +805,13 @@ void COFFDumper::printSymbol(const Symbo
         const coff_section *Assoc;
         StringRef AssocName;
         std::error_code EC;
-        if ((EC = Obj->getSection(Aux->Number, Assoc)) ||
+        if ((EC = Obj->getSection(AuxNumber, Assoc)) ||
             (EC = Obj->getSectionName(Assoc, AssocName))) {
           AssocName = "";
           error(EC);
         }
 
-        W.printNumber("AssocSection", AssocName, Aux->Number);
+        W.printNumber("AssocSection", AssocName, AuxNumber);
       }
     } else if (Symbol.isCLRToken()) {
       const coff_aux_clr_token *Aux;

Modified: llvm/trunk/tools/obj2yaml/coff2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/coff2yaml.cpp?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/coff2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/coff2yaml.cpp Mon Sep 15 14:42:42 2014
@@ -104,13 +104,15 @@ static void dumpWeakExternal(COFFYAML::S
 
 static void
 dumpSectionDefinition(COFFYAML::Symbol *Sym,
-                      const object::coff_aux_section_definition *ObjSD) {
+                      const object::coff_aux_section_definition *ObjSD,
+                      bool IsBigObj) {
   COFF::AuxiliarySectionDefinition YAMLASD;
+  int32_t AuxNumber = ObjSD->getNumber(IsBigObj);
   YAMLASD.Length = ObjSD->Length;
   YAMLASD.NumberOfRelocations = ObjSD->NumberOfRelocations;
   YAMLASD.NumberOfLinenumbers = ObjSD->NumberOfLinenumbers;
   YAMLASD.CheckSum = ObjSD->CheckSum;
-  YAMLASD.Number = ObjSD->Number;
+  YAMLASD.Number = AuxNumber;
   YAMLASD.Selection = ObjSD->Selection;
 
   Sym->SectionDefinition = YAMLASD;
@@ -182,7 +184,7 @@ void COFFDumper::dumpSymbols(unsigned Nu
         const object::coff_aux_section_definition *ObjSD =
             reinterpret_cast<const object::coff_aux_section_definition *>(
                 AuxData.data());
-        dumpSectionDefinition(&Sym, ObjSD);
+        dumpSectionDefinition(&Sym, ObjSD, Symbol.isBigObj());
       } else if (Symbol.isCLRToken()) {
         // This symbol represents a CLR token definition.
         assert(Symbol.getNumberOfAuxSymbols() == 1 &&

Modified: llvm/trunk/tools/yaml2obj/yaml2coff.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2coff.cpp?rev=217812&r1=217811&r2=217812&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2coff.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2coff.cpp Mon Sep 15 14:42:42 2014
@@ -121,8 +121,8 @@ static bool layoutCOFF(COFFParser &CP) {
 
   // The section table starts immediately after the header, including the
   // optional header.
-  SectionTableStart = sizeof(COFF::header) + CP.Obj.Header.SizeOfOptionalHeader;
-  SectionTableSize = sizeof(COFF::section) * CP.Obj.Sections.size();
+  SectionTableStart = COFF::Header16Size + CP.Obj.Header.SizeOfOptionalHeader;
+  SectionTableSize = COFF::SectionSize * CP.Obj.Sections.size();
 
   uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize;
 
@@ -163,7 +163,7 @@ static bool layoutCOFF(COFFParser &CP) {
       NumberOfAuxSymbols += 1;
     if (!i->File.empty())
       NumberOfAuxSymbols +=
-          (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
+          (i->File.size() + COFF::Symbol16Size - 1) / COFF::Symbol16Size;
     if (i->SectionDefinition)
       NumberOfAuxSymbols += 1;
     if (i->CLRToken)
@@ -224,7 +224,7 @@ zeros_impl<sizeof(T)> zeros(const T &) {
 
 bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
   OS << binary_le(CP.Obj.Header.Machine)
-     << binary_le(CP.Obj.Header.NumberOfSections)
+     << binary_le(static_cast<int16_t>(CP.Obj.Header.NumberOfSections))
      << binary_le(CP.Obj.Header.TimeDateStamp)
      << binary_le(CP.Obj.Header.PointerToSymbolTable)
      << binary_le(CP.Obj.Header.NumberOfSymbols)
@@ -277,7 +277,7 @@ bool writeCOFF(COFFParser &CP, raw_ostre
                                                      i != e; ++i) {
     OS.write(i->Header.Name, COFF::NameSize);
     OS << binary_le(i->Header.Value)
-       << binary_le(i->Header.SectionNumber)
+       << binary_le(static_cast<int16_t>(i->Header.SectionNumber))
        << binary_le(i->Header.Type)
        << binary_le(i->Header.StorageClass)
        << binary_le(i->Header.NumberOfAuxSymbols);
@@ -300,8 +300,8 @@ bool writeCOFF(COFFParser &CP, raw_ostre
          << zeros(i->WeakExternal->unused);
     if (!i->File.empty()) {
       uint32_t NumberOfAuxRecords =
-          (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
-      uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::SymbolSize;
+          (i->File.size() + COFF::Symbol16Size - 1) / COFF::Symbol16Size;
+      uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::Symbol16Size;
       uint32_t NumZeros = NumberOfAuxBytes - i->File.size();
       OS.write(i->File.data(), i->File.size());
       for (uint32_t Padding = 0; Padding < NumZeros; ++Padding)
@@ -312,9 +312,10 @@ bool writeCOFF(COFFParser &CP, raw_ostre
          << binary_le(i->SectionDefinition->NumberOfRelocations)
          << binary_le(i->SectionDefinition->NumberOfLinenumbers)
          << binary_le(i->SectionDefinition->CheckSum)
-         << binary_le(i->SectionDefinition->Number)
+         << binary_le(static_cast<int16_t>(i->SectionDefinition->Number))
          << binary_le(i->SectionDefinition->Selection)
-         << zeros(i->SectionDefinition->unused);
+         << zeros(i->SectionDefinition->unused)
+         << binary_le(static_cast<int16_t>(i->SectionDefinition->Number >> 16));
     if (i->CLRToken)
       OS << binary_le(i->CLRToken->AuxType)
          << zeros(i->CLRToken->unused1)





More information about the llvm-commits mailing list