aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp101
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);