mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
Add an option for evaluating past symbols.
When evaluating an assembly expression for a relocation, we want to stop at MCSymbols that are in the symbol table, even if they are variables. This is needed since the semantics may require that the relocation use them. That is not the case when computing the value of a symbol in the symbol table. There are no relocations in this case and we have to keep going until we hit a section or find out that the expression doesn't have an assembly time value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207445 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dc352c105f
commit
1c509556ee
@ -53,8 +53,9 @@ protected:
|
|||||||
|
|
||||||
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
|
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
|
||||||
const MCAsmLayout *Layout,
|
const MCAsmLayout *Layout,
|
||||||
const SectionAddrMap *Addrs,
|
const SectionAddrMap *Addrs, bool InSet,
|
||||||
bool InSet) const;
|
bool ForceVarExpansion) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @name Accessors
|
/// @name Accessors
|
||||||
/// @{
|
/// @{
|
||||||
@ -93,6 +94,14 @@ public:
|
|||||||
/// @result - True on success.
|
/// @result - True on success.
|
||||||
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const;
|
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const;
|
||||||
|
|
||||||
|
/// \brief Try to evaluate the expression to the form (a - b + constant) where
|
||||||
|
/// neither a nor b are variables.
|
||||||
|
///
|
||||||
|
/// This is a more aggressive variant of EvaluateAsRelocatable. The intended
|
||||||
|
/// use is for when relocations are not available, like the symbol value in
|
||||||
|
/// the symbol table.
|
||||||
|
bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const;
|
||||||
|
|
||||||
/// FindAssociatedSection - Find the "associated section" for this expression,
|
/// FindAssociatedSection - Find the "associated section" for this expression,
|
||||||
/// which is currently defined as the absolute section for constants, or
|
/// which is currently defined as the absolute section for constants, or
|
||||||
/// otherwise the section associated with the first defined symbol in the
|
/// otherwise the section associated with the first defined symbol in the
|
||||||
|
@ -496,7 +496,7 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
|
|||||||
if (Symbol->isVariable()) {
|
if (Symbol->isVariable()) {
|
||||||
const MCExpr *Expr = Symbol->getVariableValue();
|
const MCExpr *Expr = Symbol->getVariableValue();
|
||||||
MCValue Value;
|
MCValue Value;
|
||||||
if (!Expr->EvaluateAsRelocatable(Value, &Layout))
|
if (!Expr->EvaluateAsValue(Value, &Layout))
|
||||||
llvm_unreachable("Invalid expression");
|
llvm_unreachable("Invalid expression");
|
||||||
|
|
||||||
assert(!Value.getSymB());
|
assert(!Value.getSymB());
|
||||||
@ -606,7 +606,7 @@ static const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout,
|
|||||||
|
|
||||||
const MCExpr *Expr = Symbol.getVariableValue();
|
const MCExpr *Expr = Symbol.getVariableValue();
|
||||||
MCValue Value;
|
MCValue Value;
|
||||||
if (!Expr->EvaluateAsRelocatable(Value, &Layout))
|
if (!Expr->EvaluateAsValue(Value, &Layout))
|
||||||
llvm_unreachable("Invalid Expression");
|
llvm_unreachable("Invalid Expression");
|
||||||
const MCSymbolRefExpr *RefB = Value.getSymB();
|
const MCSymbolRefExpr *RefB = Value.getSymB();
|
||||||
if (RefB) {
|
if (RefB) {
|
||||||
|
@ -478,7 +478,8 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
|
|||||||
// absolutize differences across sections and that is what the MachO writer
|
// absolutize differences across sections and that is what the MachO writer
|
||||||
// uses Addrs for.
|
// uses Addrs for.
|
||||||
bool IsRelocatable =
|
bool IsRelocatable =
|
||||||
EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs);
|
EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs,
|
||||||
|
/*ForceVarExpansion*/ false);
|
||||||
|
|
||||||
// Record the current value.
|
// Record the current value.
|
||||||
Res = Value.getConstant();
|
Res = Value.getConstant();
|
||||||
@ -629,14 +630,20 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
|
|||||||
bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
|
bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
|
||||||
const MCAsmLayout *Layout) const {
|
const MCAsmLayout *Layout) const {
|
||||||
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
|
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
|
||||||
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false);
|
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
|
||||||
|
/*ForceVarExpansion*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const {
|
||||||
const MCAssembler *Asm,
|
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
|
||||||
|
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
|
||||||
|
/*ForceVarExpansion*/ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
|
||||||
const MCAsmLayout *Layout,
|
const MCAsmLayout *Layout,
|
||||||
const SectionAddrMap *Addrs,
|
const SectionAddrMap *Addrs, bool InSet,
|
||||||
bool InSet) const {
|
bool ForceVarExpansion) const {
|
||||||
++stats::MCExprEvaluate;
|
++stats::MCExprEvaluate;
|
||||||
|
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
@ -649,13 +656,14 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
|||||||
|
|
||||||
case SymbolRef: {
|
case SymbolRef: {
|
||||||
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
|
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
|
||||||
|
bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF;
|
||||||
const MCSymbol &Sym = SRE->getSymbol();
|
const MCSymbol &Sym = SRE->getSymbol();
|
||||||
const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
|
const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
|
||||||
|
|
||||||
// Evaluate recursively if this is a variable.
|
// Evaluate recursively if this is a variable.
|
||||||
if (Sym.isVariable()) {
|
if (Sym.isVariable() && !IsWeakRef) {
|
||||||
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm, Layout,
|
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
|
||||||
Addrs, true)) {
|
Res, Asm, Layout, Addrs, true, ForceVarExpansion)) {
|
||||||
const MCSymbolRefExpr *A = Res.getSymA();
|
const MCSymbolRefExpr *A = Res.getSymA();
|
||||||
const MCSymbolRefExpr *B = Res.getSymB();
|
const MCSymbolRefExpr *B = Res.getSymB();
|
||||||
|
|
||||||
@ -669,9 +677,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
|||||||
if (!A && !B)
|
if (!A && !B)
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
if (ForceVarExpansion)
|
||||||
|
return true;
|
||||||
bool IsSymbol = A && A->getSymbol().isDefined();
|
bool IsSymbol = A && A->getSymbol().isDefined();
|
||||||
bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF;
|
if (!IsSymbol)
|
||||||
if (!IsSymbol && !IsWeakRef)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -685,8 +694,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
|||||||
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
|
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
|
||||||
MCValue Value;
|
MCValue Value;
|
||||||
|
|
||||||
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
|
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs,
|
||||||
Addrs, InSet))
|
InSet, ForceVarExpansion))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (AUE->getOpcode()) {
|
switch (AUE->getOpcode()) {
|
||||||
@ -719,10 +728,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
|||||||
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
|
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
|
||||||
MCValue LHSValue, RHSValue;
|
MCValue LHSValue, RHSValue;
|
||||||
|
|
||||||
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
|
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Addrs,
|
||||||
Addrs, InSet) ||
|
InSet, ForceVarExpansion) ||
|
||||||
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
|
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Addrs,
|
||||||
Addrs, InSet))
|
InSet, ForceVarExpansion))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// We only support a few operations on non-constant expressions, handle
|
// We only support a few operations on non-constant expressions, handle
|
||||||
|
@ -71,3 +71,62 @@ sym_f = sym_a + (1 - 1)
|
|||||||
// CHECK-NEXT: Other: 0
|
// CHECK-NEXT: Other: 0
|
||||||
// CHECK-NEXT: Section: .data
|
// CHECK-NEXT: Section: .data
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
|
|
||||||
|
.globl test2_a
|
||||||
|
.globl test2_b
|
||||||
|
.globl test2_c
|
||||||
|
.globl test2_d
|
||||||
|
.globl test2_e
|
||||||
|
test2_a:
|
||||||
|
.long 0
|
||||||
|
test2_b = test2_a
|
||||||
|
test2_c:
|
||||||
|
.long 0
|
||||||
|
test2_d = test2_c
|
||||||
|
test2_e = test2_d - test2_b
|
||||||
|
// CHECK: Symbol {
|
||||||
|
// CHECK: Name: test2_a
|
||||||
|
// CHECK-NEXT: Value: 0x5
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Global
|
||||||
|
// CHECK-NEXT: Type: None
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .data
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: test2_b
|
||||||
|
// CHECK-NEXT: Value: 0x5
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Global
|
||||||
|
// CHECK-NEXT: Type: None
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .data
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: test2_c
|
||||||
|
// CHECK-NEXT: Value: 0x9
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Global
|
||||||
|
// CHECK-NEXT: Type: None
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .data
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: test2_d
|
||||||
|
// CHECK-NEXT: Value: 0x9
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Global
|
||||||
|
// CHECK-NEXT: Type: None
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .data
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: test2_e
|
||||||
|
// CHECK-NEXT: Value: 0x4
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Global
|
||||||
|
// CHECK-NEXT: Type: None
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: Absolute
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
Loading…
Reference in New Issue
Block a user