This commit is contained in:
Nguyen Anh Quynh
2016-06-05 18:19:13 +08:00
parent 1dc1e88a50
commit eabf8a7434
4 changed files with 44 additions and 20 deletions
+1 -1
View File
@@ -61,7 +61,7 @@ protected:
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet) const;
const SectionAddrMap *Addrs, bool InSet, bool &valid) const;
public:
/// \name Accessors
+1 -1
View File
@@ -95,7 +95,7 @@ public:
bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolRefExpr *A,
const MCSymbolRefExpr *B,
bool InSet) const;
bool InSet, bool &valid) const;
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &A,
+35 -17
View File
@@ -449,8 +449,9 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return true;
}
bool valid;
bool IsRelocatable =
evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet);
evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet, valid);
// Record the current value.
Res = Value.getConstant();
@@ -462,7 +463,8 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
static void AttemptToFoldSymbolOffsetDifference(
const MCAssembler *Asm, const MCAsmLayout *Layout,
const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A,
const MCSymbolRefExpr *&B, int64_t &Addend) {
const MCSymbolRefExpr *&B, int64_t &Addend, bool &valid) {
valid = true;
if (!A || !B)
return;
@@ -472,8 +474,10 @@ static void AttemptToFoldSymbolOffsetDifference(
if (SA.isUndefined() || SB.isUndefined())
return;
if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet, valid))
return;
if (!valid)
return;
if (SA.getFragment() == SB.getFragment() && !SA.isVariable() &&
!SB.isVariable()) {
@@ -539,7 +543,8 @@ static bool
EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout,
const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS,
const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B,
int64_t RHS_Cst, MCValue &Res) {
int64_t RHS_Cst, MCValue &Res, bool &valid)
{
// FIXME: This routine (and other evaluation parts) are *incredibly* sloppy
// about dealing with modifiers. This will ultimately bite us, one day.
const MCSymbolRefExpr *LHS_A = LHS.getSymA();
@@ -565,13 +570,21 @@ EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout,
// Since we are attempting to be as aggressive as possible about folding, we
// attempt to evaluate each possible alternative.
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B,
Result_Cst);
Result_Cst, valid);
if (!valid)
return false;
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B,
Result_Cst);
Result_Cst, valid);
if (!valid)
return false;
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B,
Result_Cst);
Result_Cst, valid);
if (!valid)
return false;
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B,
Result_Cst);
Result_Cst, valid);
if (!valid)
return false;
}
// We can't represent the addition or subtraction of two symbols.
@@ -592,15 +605,17 @@ bool MCExpr::evaluateAsRelocatable(MCValue &Res,
const MCFixup *Fixup) const
{
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
bool valid;
return evaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
false);
false, valid);
}
bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const
{
MCAssembler *Assembler = &Layout.getAssembler();
bool valid;
return evaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr,
true);
true, valid);
}
static bool canExpand(const MCSymbol &Sym, bool InSet) {
@@ -620,7 +635,7 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs,
bool InSet) const
bool InSet, bool &valid) const
{
switch (getKind()) {
case Target:
@@ -639,8 +654,9 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None &&
canExpand(Sym, InSet)) {
bool IsMachO = SRE->hasSubsectionsViaSymbols();
bool valid;
if (Sym.getVariableValue()->evaluateAsRelocatableImpl(
Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) {
Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO, valid)) {
if (!IsMachO)
return true;
@@ -665,8 +681,9 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
bool valid;
if (!AUE->getSubExpr()->evaluateAsRelocatableImpl(Value, Asm, Layout, Fixup,
Addrs, InSet))
Addrs, InSet, valid))
return false;
switch (AUE->getOpcode()) {
@@ -698,11 +715,12 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
case Binary: {
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
bool valid;
if (!ABE->getLHS()->evaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup,
Addrs, InSet) ||
Addrs, InSet, valid) ||
!ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup,
Addrs, InSet))
Addrs, InSet, valid))
return false;
// We only support a few operations on non-constant expressions, handle
@@ -715,12 +733,12 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
// Negate RHS and add.
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
-RHSValue.getConstant(), Res);
-RHSValue.getConstant(), Res, valid);
case MCBinaryExpr::Add:
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymA(), RHSValue.getSymB(),
RHSValue.getConstant(), Res);
RHSValue.getConstant(), Res, valid);
}
}
+7 -1
View File
@@ -19,7 +19,9 @@ MCObjectWriter::~MCObjectWriter() {
bool MCObjectWriter::isSymbolRefDifferenceFullyResolved(
const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B,
bool InSet) const {
bool InSet, bool &valid) const
{
valid = true;
// Modified symbol references cannot be resolved.
if (A->getKind() != MCSymbolRefExpr::VK_None ||
B->getKind() != MCSymbolRefExpr::VK_None)
@@ -33,6 +35,10 @@ bool MCObjectWriter::isSymbolRefDifferenceFullyResolved(
if (!SA.getFragment() || !SB.getFragment())
return false;
if (!SA.isInSection()) {
valid = false;
return false;
}
return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, SB, InSet);
}