diff options
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
| -rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 101 | 
1 files changed, 57 insertions, 44 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 9ffecd99df68..b774852eabe6 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -36,6 +36,7 @@  #include "llvm/Support/Endian.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/JamCRC.h" +#include "llvm/Support/LEB128.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h"  #include <algorithm> @@ -58,8 +59,6 @@ namespace {  using name = SmallString<COFF::NameSize>;  enum AuxiliaryType { -  ATFunctionDefinition, -  ATbfAndefSymbol,    ATWeakExternal,    ATFile,    ATSectionDefinition @@ -147,6 +146,10 @@ public:    bool UseBigObj; +  bool EmitAddrsigSection = false; +  MCSectionCOFF *AddrsigSection; +  std::vector<const MCSymbol *> AddrsigSyms; +    WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,                        raw_pwrite_stream &OS); @@ -206,6 +209,11 @@ public:    void assignSectionNumbers();    void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout); +  void emitAddrsigSection() override { EmitAddrsigSection = true; } +  void addAddrsigSymbol(const MCSymbol *Sym) override { +    AddrsigSyms.push_back(Sym); +  } +    uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;  }; @@ -515,24 +523,6 @@ void WinCOFFObjectWriter::WriteAuxiliarySymbols(      const COFFSymbol::AuxiliarySymbols &S) {    for (const AuxSymbol &i : S) {      switch (i.AuxType) { -    case ATFunctionDefinition: -      W.write<uint32_t>(i.Aux.FunctionDefinition.TagIndex); -      W.write<uint32_t>(i.Aux.FunctionDefinition.TotalSize); -      W.write<uint32_t>(i.Aux.FunctionDefinition.PointerToLinenumber); -      W.write<uint32_t>(i.Aux.FunctionDefinition.PointerToNextFunction); -      W.OS.write_zeros(sizeof(i.Aux.FunctionDefinition.unused)); -      if (UseBigObj) -        W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); -      break; -    case ATbfAndefSymbol: -      W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused1)); -      W.write<uint16_t>(i.Aux.bfAndefSymbol.Linenumber); -      W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused2)); -      W.write<uint32_t>(i.Aux.bfAndefSymbol.PointerToNextFunction); -      W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused3)); -      if (UseBigObj) -        W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); -      break;      case ATWeakExternal:        W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);        W.write<uint32_t>(i.Aux.WeakExternal.Characteristics); @@ -568,10 +558,9 @@ void WinCOFFObjectWriter::writeSectionHeaders() {    std::vector<COFFSection *> Arr;    for (auto &Section : Sections)      Arr.push_back(Section.get()); -  llvm::sort(Arr.begin(), Arr.end(), -             [](const COFFSection *A, const COFFSection *B) { -               return A->Number < B->Number; -             }); +  llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) { +    return A->Number < B->Number; +  });    for (auto &Section : Arr) {      if (Section->Number == -1) @@ -630,14 +619,9 @@ void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,    // Write the section contents.    if (Sec.Header.PointerToRawData != 0) { -    assert(W.OS.tell() <= Sec.Header.PointerToRawData && +    assert(W.OS.tell() == Sec.Header.PointerToRawData &&             "Section::PointerToRawData is insane!"); -    unsigned PaddingSize = Sec.Header.PointerToRawData - W.OS.tell(); -    assert(PaddingSize < 4 && -           "Should only need at most three bytes of padding!"); -    W.OS.write_zeros(PaddingSize); -      uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);      // Update the section definition auxiliary symbol to record the CRC. @@ -677,6 +661,13 @@ void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,  void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,                                                     const MCAsmLayout &Layout) { +  if (EmitAddrsigSection) { +    AddrsigSection = Asm.getContext().getCOFFSection( +        ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE, +        SectionKind::getMetadata()); +    Asm.registerSection(*AddrsigSection); +  } +    // "Define" each section & symbol. This creates section & symbol    // entries in the staging area.    for (const auto &Section : Asm) @@ -915,10 +906,7 @@ void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,      Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);      if (IsPhysicalSection(Sec)) { -      // Align the section data to a four byte boundary. -      Offset = alignTo(Offset, 4);        Sec->Header.PointerToRawData = Offset; -        Offset += Sec->Header.SizeOfRawData;      } @@ -1020,22 +1008,47 @@ uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,        continue;      const MCSectionCOFF &MCSec = *Section->MCSection; +    const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol(); +    assert(AssocMCSym); + +    // It's an error to try to associate with an undefined symbol or a symbol +    // without a section. +    if (!AssocMCSym->isInSection()) { +      Asm.getContext().reportError( +          SMLoc(), Twine("cannot make section ") + MCSec.getSectionName() + +                       Twine(" associative with sectionless symbol ") + +                       AssocMCSym->getName()); +      continue; +    } -    const MCSymbol *COMDAT = MCSec.getCOMDATSymbol(); -    assert(COMDAT); -    COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT); -    assert(COMDATSymbol); -    COFFSection *Assoc = COMDATSymbol->Section; -    if (!Assoc) -      report_fatal_error( -          Twine("Missing associated COMDAT section for section ") + -          MCSec.getSectionName()); +    const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection()); +    assert(SectionMap.count(AssocMCSec)); +    COFFSection *AssocSec = SectionMap[AssocMCSec];      // Skip this section if the associated section is unused. -    if (Assoc->Number == -1) +    if (AssocSec->Number == -1)        continue; -    Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number; +    Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number; +  } + +  // Create the contents of the .llvm_addrsig section. +  if (EmitAddrsigSection) { +    auto Frag = new MCDataFragment(AddrsigSection); +    Frag->setLayoutOrder(0); +    raw_svector_ostream OS(Frag->getContents()); +    for (const MCSymbol *S : AddrsigSyms) { +      if (!S->isTemporary()) { +        encodeULEB128(S->getIndex(), OS); +        continue; +      } + +      MCSection *TargetSection = &S->getSection(); +      assert(SectionMap.find(TargetSection) != SectionMap.end() && +             "Section must already have been defined in " +             "executePostLayoutBinding!"); +      encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS); +    }    }    assignFileOffsets(Asm, Layout);  | 
