aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCELFStreamer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCELFStreamer.cpp')
-rw-r--r--lib/MC/MCELFStreamer.cpp63
1 files changed, 50 insertions, 13 deletions
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 8b9bdb14a0..b24deb9c51 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -12,11 +12,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCELFStreamer.h"
+
+#include "MCELF.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
@@ -32,7 +36,6 @@
using namespace llvm;
-
inline void MCELFStreamer::SetSection(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind) {
SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
@@ -100,6 +103,23 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
llvm_unreachable("invalid assembler flag!");
}
+void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
+ // FIXME: Anything needed here to flag the function as thumb?
+
+ getAssembler().setIsThumbFunc(Func);
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
+ SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
+}
+
+void MCELFStreamer::EmitAssignment(MCSymbol* Symbol, const MCExpr* Value) {
+ // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
+ // MCObjectStreamer.
+ // FIXME: Lift context changes into super class.
+ getAssembler().getOrCreateSymbolData(*Symbol);
+ Symbol->setVariableValue(AddValueSymbols(Value));
+}
+
void MCELFStreamer::ChangeSection(const MCSection *Section) {
const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
if (Grp)
@@ -260,6 +280,7 @@ void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {
fixSymbolsInTLSFixups(Value);
MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace);
+ getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD
}
@@ -328,10 +349,10 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i)
fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
+ getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD
}
void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
- MCDataFragment *DF = getOrCreateDataFragment();
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
@@ -342,12 +363,30 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
fixSymbolsInTLSFixups(Fixups[i].getValue());
- // Add the fixups and data.
- for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
- Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
- DF->getFixups().push_back(Fixups[i]);
+ // @LOCALMOD-BEGIN
+ MCSectionData *SD = getCurrentSectionData();
+
+ if (Fixups.size() > 0 || !SD->isBundlingEnabled()) {
+ MCDataFragment *DF;
+ if (SD->isBundlingEnabled())
+ DF = new MCDataFragment(SD);
+ else
+ DF = getOrCreateDataFragment();
+
+ // Add the fixups and data.
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+ DF->addFixup(Fixups[i]);
+ }
+ DF->getContents().append(Code.begin(), Code.end());
+ } else {
+ MCTinyFragment *TF = dyn_cast_or_null<MCTinyFragment>(getCurrentFragment());
+ if (!TF || SD->ShouldCreateNewFragment(Code.size()))
+ TF = new MCTinyFragment(SD);
+ TF->getContents().append(Code.begin(), Code.end());
}
- DF->getContents().append(Code.begin(), Code.end());
+ SD->UpdateBundleOffset(Code.size());
+ // @LOCALMOD-END
}
void MCELFStreamer::FinishImpl() {
@@ -375,7 +414,9 @@ void MCELFStreamer::FinishImpl() {
this->MCObjectStreamer::FinishImpl();
}
-void MCELFStreamer::EmitTCEntry(const MCSymbol &S) {
+
+void MCELFStreamer::EmitTCEntry(const MCSymbol &S)
+{
// Creates a R_PPC64_TOC relocation
MCObjectStreamer::EmitSymbolValue(&S, 8, 0);
}
@@ -391,10 +432,6 @@ MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
return S;
}
-void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
- llvm_unreachable("Generic ELF doesn't support this directive");
-}
-
void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("ELF doesn't support this directive");
}