diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 1493fa284328c950d5fd8a50aa243b0457286dfa..eba5b088f7503216c2c19c8445458ce5b465efdd 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -150,6 +150,7 @@ public: unsigned Size) override; bool mayHaveInstructions(MCSection &Sec) const override; + uint64_t getCurrentFragmentSize() override; }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 22db69f0d088b7289b4cee71aa50921d8c05ac9f..d55b5da6a98b36c9d030d3774f7db28e5f2a6b54 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -230,6 +230,10 @@ public: void generateCompactUnwindEncodings(MCAsmBackend *MAB); + // \brief Returns the current size of the fragment to which the streamer + // is emitting code to. + virtual uint64_t getCurrentFragmentSize() {return 0; } + /// \name Assembly File Formatting. /// @{ diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index cbb96e5a7e8e3550d297c99eef4ccf7746aa75fd..a3648bde14ca1d06c09598c8304953c6a117207c 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -463,7 +463,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); - DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } @@ -473,7 +473,7 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); - DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 8, 0); } @@ -526,3 +526,10 @@ unsigned int MCObjectStreamer::FinishImpl() return KsError; } + +uint64_t MCObjectStreamer::getCurrentFragmentSize() { + auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); + if (nullptr != F) + return F->getContents().size(); + return 0; +} diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 9bc787c665de2f3d46b0dc5900dcc93a83e92ae0..44a6179693c984ee83cc94069c0a2bcfb9780553 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1680,8 +1680,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // First query the target-specific parser. It will return 'true' if it // isn't interested in this directive. - if (!getTargetParser().ParseDirective(ID)) - return false; + uint64_t BytesInFragment = getStreamer().getCurrentFragmentSize(); + if (!getTargetParser().ParseDirective(ID)){ + // increment the address for the next statement if the directive + // has emitted any value to the streamer. + Address += getStreamer().getCurrentFragmentSize() - BytesInFragment; + return false; + } // Next, check the extension directive map to see if any extension has // registered itself to parse this directive.