#include "llvm/Support/LEB128.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/MC/MCSectionELF.h"
#include <tuple>
using namespace llvm;
// If SD is a variable, evaluate it.
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
+ if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
const MCExpr *Expr = Symbol.getVariableValue();
MCValue Value;
- if (!Expr->EvaluateAsValue(Value, this))
+ if (!Expr->EvaluateAsValue(Value, this, nullptr))
llvm_unreachable("Invalid Expression");
const MCSymbolRefExpr *RefB = Value.getSymB();
: Section(&_Section),
Ordinal(~UINT32_C(0)),
Alignment(1),
- BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false),
+ BundleLockState(NotBundleLocked),
+ BundleLockNestingDepth(0),
+ BundleGroupBeforeFirstInst(false),
HasInstructions(false)
{
if (A)
return IP;
}
+void MCSectionData::setBundleLockState(BundleLockStateType NewState) {
+ if (NewState == NotBundleLocked) {
+ if (BundleLockNestingDepth == 0) {
+ report_fatal_error("Mismatched bundle_lock/unlock directives");
+ }
+ if (--BundleLockNestingDepth == 0) {
+ BundleLockState = NotBundleLocked;
+ }
+ return;
+ }
+
+ // If any of the directives is an align_to_end directive, the whole nested
+ // group is align_to_end. So don't downgrade from align_to_end to just locked.
+ if (BundleLockState != BundleLockedAlignToEnd) {
+ BundleLockState = NewState;
+ }
+ ++BundleLockNestingDepth;
+}
+
/* *** */
MCSymbolData::MCSymbolData() : Symbol(nullptr) {}
MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
uint64_t _Offset, MCAssembler *A)
- : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
- IsExternal(false), IsPrivateExtern(false),
- CommonSize(0), SymbolSize(nullptr), CommonAlign(0),
- Flags(0), Index(0)
-{
+ : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
+ SymbolSize(nullptr), CommonAlign(-1U), Flags(0), Index(0) {
if (A)
A->getSymbolList().push_back(this);
}
MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
raw_ostream &OS_)
- : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
- OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false),
- SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
+ : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
+ OS(OS_), BundleAlignSize(0), RelaxAll(false),
+ SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
}
SymbolMap.clear();
IndirectSymbols.clear();
DataRegions.clear();
+ LinkerOptions.clear();
+ FileNames.clear();
ThumbFuncs.clear();
+ BundleAlignSize = 0;
RelaxAll = false;
- NoExecStack = false;
SubsectionsViaSymbols = false;
ELFHeaderEFlags = 0;
+ LOHContainer.reset();
+ VersionMinInfo.Major = 0;
// reset objects owned by us
getBackend().reset();
return SD->getFragment()->getAtom();
}
+// Try to fully compute Expr to an absolute value and if that fails produce
+// a relocatable expr.
+// FIXME: Should this be the behavior of EvaluateAsRelocatable itself?
+static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout,
+ const MCFixup &Fixup, MCValue &Target) {
+ if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) {
+ if (Target.isAbsolute())
+ return true;
+ }
+ return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup);
+}
+
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const {
++stats::evaluateFixup;
- if (!Fixup.getValue()->EvaluateAsRelocatable(Target, &Layout))
+ // FIXME: This code has some duplication with RecordRelocation. We should
+ // probably merge the two into a single callback that tries to evaluate a
+ // fixup and records a relocation if one is needed.
+ const MCExpr *Expr = Fixup.getValue();
+ if (!evaluate(*Expr, Layout, Fixup, Target))
getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
assert(DF.fixup_begin() == DF.fixup_end() &&
"Cannot have fixups in virtual section!");
for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)
- assert(DF.getContents()[i] == 0 &&
- "Invalid data value for virtual section!");
+ if (DF.getContents()[i]) {
+ if (auto *ELFSec = dyn_cast<const MCSectionELF>(&SD->getSection()))
+ report_fatal_error("non-zero initializer found in section '" +
+ ELFSec->getSectionName() + "'");
+ else
+ report_fatal_error("non-zero initializer found in virtual section");
+ }
break;
}
case MCFragment::FT_Align:
}
bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
- int64_t Value = 0;
uint64_t OldSize = LF.getContents().size();
- bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t Value = LF.getValue().evaluateKnownAbsolute(Layout);
SmallString<8> &Data = LF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF) {
MCContext &Context = Layout.getAssembler().getContext();
- int64_t AddrDelta = 0;
uint64_t OldSize = DF.getContents().size();
- bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout);
int64_t LineDelta;
LineDelta = DF.getLineDelta();
SmallString<8> &Data = DF.getContents();
bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
MCDwarfCallFrameFragment &DF) {
MCContext &Context = Layout.getAssembler().getContext();
- int64_t AddrDelta = 0;
uint64_t OldSize = DF.getContents().size();
- bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout);
SmallString<8> &Data = DF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
OS << "]>";
}
-void MCSymbolData::dump() {
+void MCSymbolData::dump() const {
raw_ostream &OS = llvm::errs();
OS << "<MCSymbolData Symbol:" << getSymbol()
- << " Fragment:" << getFragment() << " Offset:" << getOffset()
- << " Flags:" << getFlags() << " Index:" << getIndex();
+ << " Fragment:" << getFragment();
+ if (!isCommon())
+ OS << " Offset:" << getOffset();
+ OS << " Flags:" << getFlags() << " Index:" << getIndex();
if (isCommon())
OS << " (common, size:" << getCommonSize()
<< " align: " << getCommonAlignment() << ")";