aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp43
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp4
-rw-r--r--llvm/lib/MC/MCParser/MCTargetAsmParser.cpp5
-rw-r--r--llvm/lib/MC/MCSectionELF.cpp4
-rw-r--r--llvm/lib/MC/MCStreamer.cpp13
5 files changed, 43 insertions, 26 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 67433f2..d5b8f22 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -106,26 +106,12 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
MCDwarfFrameEmitter::Emit(*this, MAB, false);
}
-static bool canReuseDataFragment(const MCFragment &F,
- const MCAssembler &Assembler,
- const MCSubtargetInfo *STI) {
- if (!F.hasInstructions())
- return true;
- // Do not add data after a linker-relaxable instruction. The difference
- // between a new label and a label at or before the linker-relaxable
- // instruction cannot be resolved at assemble-time.
- if (F.isLinkerRelaxable())
- return false;
- // If the subtarget is changed mid fragment we start a new fragment to record
- // the new STI.
- return !STI || F.getSubtargetInfo() == STI;
-}
-
-MCFragment *
-MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
+MCFragment *MCObjectStreamer::getOrCreateDataFragment() {
+ // TODO: Start a new fragment whenever finalizing the variable-size tail of a
+ // previous one, so that all getOrCreateDataFragment calls can be replaced
+ // with getCurrentFragment
auto *F = getCurrentFragment();
- if (F->getKind() != MCFragment::FT_Data ||
- !canReuseDataFragment(*F, *Assembler, STI)) {
+ if (F->getKind() != MCFragment::FT_Data) {
F = getContext().allocFragment<MCFragment>();
insert(F);
}
@@ -363,16 +349,23 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
F->doneAppending();
if (!Fixups.empty())
F->appendFixups(Fixups);
+ F->setHasInstructions(STI);
+ bool MarkedLinkerRelaxable = false;
for (auto &Fixup : MutableArrayRef(F->getFixups()).slice(FixupStartIndex)) {
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
- if (Fixup.isLinkerRelaxable()) {
- F->setLinkerRelaxable();
+ if (!Fixup.isLinkerRelaxable())
+ continue;
+ F->setLinkerRelaxable();
+ // Do not add data after a linker-relaxable instruction. The difference
+ // between a new label and a label at or before the linker-relaxable
+ // instruction cannot be resolved at assemble-time.
+ if (!MarkedLinkerRelaxable) {
+ MarkedLinkerRelaxable = true;
getCurrentSectionOnly()->setLinkerRelaxable();
+ newFragment();
}
}
-
- F->setHasInstructions(STI);
}
void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
@@ -568,8 +561,10 @@ void MCObjectStreamer::emitCodeAlignment(Align Alignment,
// if the alignment is larger than the minimum NOP size.
unsigned Size;
if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F,
- Size))
+ Size)) {
getCurrentSectionOnly()->setLinkerRelaxable();
+ newFragment();
+ }
}
void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index ec8b402..c7c3df3 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -571,7 +571,7 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) {
return TokError("expected end of directive");
}
- if (Mergeable)
+ if (Mergeable || TypeName == "llvm_cfi_jump_table")
if (parseMergeSize(Size))
return true;
if (Flags & ELF::SHF_LINK_ORDER)
@@ -637,6 +637,8 @@ EndStmt:
Type = ELF::SHT_LLVM_LTO;
else if (TypeName == "llvm_jt_sizes")
Type = ELF::SHT_LLVM_JT_SIZES;
+ else if (TypeName == "llvm_cfi_jump_table")
+ Type = ELF::SHT_LLVM_CFI_JUMP_TABLE;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
diff --git a/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp b/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
index 665d92e..7f09349 100644
--- a/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
@@ -9,6 +9,7 @@
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCRegister.h"
+#include "llvm/MC/MCStreamer.h"
using namespace llvm;
@@ -22,6 +23,10 @@ MCTargetAsmParser::~MCTargetAsmParser() = default;
MCSubtargetInfo &MCTargetAsmParser::copySTI() {
MCSubtargetInfo &STICopy = getContext().getSubtargetCopy(getSTI());
STI = &STICopy;
+ // The returned STI will likely be modified. Create a new fragment to prevent
+ // mixing STI values within a fragment.
+ if (getStreamer().getCurrentFragment())
+ getStreamer().newFragment();
return STICopy;
}
diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp
index cc7cdf2..299fe40 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -176,11 +176,13 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << "llvm_lto";
else if (Type == ELF::SHT_LLVM_JT_SIZES)
OS << "llvm_jt_sizes";
+ else if (Type == ELF::SHT_LLVM_CFI_JUMP_TABLE)
+ OS << "llvm_cfi_jump_table";
else
OS << "0x" << Twine::utohexstr(Type);
if (EntrySize) {
- assert(Flags & ELF::SHF_MERGE);
+ assert((Flags & ELF::SHF_MERGE) || Type == ELF::SHT_LLVM_CFI_JUMP_TABLE);
OS << "," << EntrySize;
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index d814ab88..c3ecf8f 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1404,6 +1404,19 @@ MCSymbol *MCStreamer::endSection(MCSection *Section) {
return Sym;
}
+void MCStreamer::insert(MCFragment *F) {
+ auto *Sec = CurFrag->getParent();
+ F->setParent(Sec);
+ F->setLayoutOrder(CurFrag->getLayoutOrder() + 1);
+ CurFrag->Next = F;
+ CurFrag = F;
+ Sec->curFragList()->Tail = F;
+}
+
+void MCStreamer::newFragment() {
+ insert(getContext().allocFragment<MCFragment>());
+}
+
static VersionTuple
targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
VersionTuple TargetVersion) {