本文整理汇总了C++中MCValue::getConstant方法的典型用法代码示例。如果您正苦于以下问题:C++ MCValue::getConstant方法的具体用法?C++ MCValue::getConstant怎么用?C++ MCValue::getConstant使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MCValue
的用法示例。
在下文中一共展示了MCValue::getConstant方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
void X86MachObjectWriter::RecordTLVPRelocation(MachObjectWriter *Writer,
const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP &&
!is64Bit() &&
"Should only be called with a 32-bit TLVP relocation!");
unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
unsigned IsPCRel = 0;
// We're only going to have a second symbol in pic mode and it'll be a
// subtraction from the picbase. For 32-bit pic the addend is the difference
// between the picbase and the next address. For 32-bit static the addend is
// zero.
if (Target.getSymB()) {
// If this is a subtraction then we're pcrel.
uint32_t FixupAddress =
Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
IsPCRel = 1;
FixedValue =
FixupAddress -
Writer->getSymbolAddress(Target.getSymB()->getSymbol(), Layout) +
Target.getConstant();
FixedValue += 1ULL << Log2Size;
} else {
FixedValue = 0;
}
// struct relocation_info (8 bytes)
MachO::any_relocation_info MRE;
MRE.r_word0 = Value;
MRE.r_word1 =
(IsPCRel << 24) | (Log2Size << 25) | (MachO::GENERIC_RELOC_TLV << 28);
Writer->addRelocation(&Target.getSymA()->getSymbol(), Fragment->getParent(),
MRE);
}
示例2: EvaluateSymbolicAdd
static bool EvaluateSymbolicAdd(const MCValue &LHS, const MCSymbol *RHS_A,
const MCSymbol *RHS_B, int64_t RHS_Cst,
MCValue &Res) {
// We can't add or subtract two symbols.
if ((LHS.getSymA() && RHS_A) ||
(LHS.getSymB() && RHS_B))
return false;
const MCSymbol *A = LHS.getSymA() ? LHS.getSymA() : RHS_A;
const MCSymbol *B = LHS.getSymB() ? LHS.getSymB() : RHS_B;
if (B) {
// If we have a negated symbol, then we must have also have a non-negated
// symbol in order to encode the expression. We can do this check later to
// permit expressions which eventually fold to a representable form -- such
// as (a + (0 - b)) -- if necessary.
if (!A)
return false;
}
Res = MCValue::get(A, B, LHS.getConstant() + RHS_Cst);
return true;
}
示例3: EvaluateAsAbsolute
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const SectionAddrMap *Addrs) const {
MCValue Value;
// Fast path constants.
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(this)) {
Res = CE->getValue();
return true;
}
// FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us
// absolutize differences across sections and that is what the MachO writer
// uses Addrs for.
bool IsRelocatable =
EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs);
// Record the current value.
Res = Value.getConstant();
return IsRelocatable && Value.isAbsolute();
}
示例4: getSymbolOffsetImpl
static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
const MCSymbolData *SD, bool ReportError,
uint64_t &Val) {
const MCSymbol &S = SD->getSymbol();
if (!S.isVariable())
return getLabelOffset(Layout, *SD, ReportError, Val);
// If SD is a variable, evaluate it.
MCValue Target;
if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
uint64_t Offset = Target.getConstant();
const MCAssembler &Asm = Layout.getAssembler();
const MCSymbolRefExpr *A = Target.getSymA();
if (A) {
uint64_t ValA;
if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError,
ValA))
return false;
Offset += ValA;
}
const MCSymbolRefExpr *B = Target.getSymB();
if (B) {
uint64_t ValB;
if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError,
ValB))
return false;
Offset -= ValB;
}
Val = Offset;
return true;
}
示例5: getSymbolAddress
uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
const MCAsmLayout &Layout) const {
const MCSymbol &S = SD->getSymbol();
// If this is a variable, then recursively evaluate now.
if (S.isVariable()) {
if (const MCConstantExpr *C =
dyn_cast<const MCConstantExpr>(S.getVariableValue()))
return C->getValue();
MCValue Target;
if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
// Verify that any used symbols are defined.
if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
report_fatal_error("unable to evaluate offset to undefined symbol '" +
Target.getSymA()->getSymbol().getName() + "'");
if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
report_fatal_error("unable to evaluate offset to undefined symbol '" +
Target.getSymB()->getSymbol().getName() + "'");
uint64_t Address = Target.getConstant();
if (Target.getSymA())
Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
Target.getSymA()->getSymbol()), Layout);
if (Target.getSymB())
Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
Target.getSymB()->getSymbol()), Layout);
return Address;
}
return getSectionAddress(SD->getFragment()->getParent()) +
Layout.getSymbolOffset(SD);
}
示例6: RecordRelocation
void SVMMemoryLayout::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout, const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)
{
SVM::Fixups kind = (SVM::Fixups) Fixup.getKind();
switch (kind) {
case SVM::fixup_fnstack: {
/*
* Function stack adjustment annotation. The adjustment amount is
* stored in the first argument of a binary op.
* (See SVMMCCodeEmitter::EncodeInstruction)
*
* We store this offset for later, in our FNStackMap, indexed
* by the address of the FNStack pseudo-op itself.
*/
FNStackMap[std::make_pair(Fragment->getParent(),
Layout.getFragmentOffset(Fragment))] = (int)Target.getConstant();
break;
}
default: {
/*
* All other fixups are applied later, in ApplyLateFixups().
* This is necessary because other fixup types can depend on
* the FNStack values collected above.
*/
SVMLateFixup LF((MCFragment *) Fragment, Fixup, Target);
LateFixupList.push_back(LF);
// This gets OR'ed with the fixup later. Zero it.
FixedValue = 0;
break;
}
}
}
示例7: evaluateFixup
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const {
++stats::evaluateFixup;
// 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 (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup))
getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
bool IsResolved;
if (IsPCRel) {
if (Target.getSymB()) {
IsResolved = false;
} else if (!Target.getSymA()) {
IsResolved = false;
} else {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol &SA = A->getSymbol();
if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) {
IsResolved = false;
} else {
IsResolved = getWriter().isSymbolRefDifferenceFullyResolvedImpl(
*this, SA, *DF, false, true);
}
}
} else {
IsResolved = Target.isAbsolute();
}
Value = Target.getConstant();
if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol();
if (Sym.isDefined())
Value += Layout.getSymbolOffset(Sym);
}
if (const MCSymbolRefExpr *B = Target.getSymB()) {
const MCSymbol &Sym = B->getSymbol();
if (Sym.isDefined())
Value -= Layout.getSymbolOffset(Sym);
}
bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
assert((ShouldAlignPC ? IsPCRel : true) &&
"FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!");
if (IsPCRel) {
uint32_t Offset = Layout.getFragmentOffset(DF) + Fixup.getOffset();
// A number of ARM fixups in Thumb mode require that the effective PC
// address be determined as the 32-bit aligned version of the actual offset.
if (ShouldAlignPC) Offset &= ~0x3;
Value -= Offset;
}
// Let the backend adjust the fixup value if necessary, including whether
// we need a relocation.
Backend.processFixupValue(*this, Layout, Fixup, DF, Target, Value,
IsResolved);
return IsResolved;
}
示例8: RecordRelocation
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
const MCSymbol &A = Symbol.AliasedSymbol();
MCSymbolData &A_SD = Asm.getSymbolData(A);
MCSectionData const *SectionData = Fragment->getParent();
// Mark this symbol as requiring an entry in the symbol table.
assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() &&
"Section must already have been defined in ExecutePostLayoutBinding!");
assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() &&
"Symbol must already have been defined in ExecutePostLayoutBinding!");
COFFSection *coff_section = SectionMap[&SectionData->getSection()];
COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()];
const MCSymbolRefExpr *SymA = Target.getSymA();
const MCSymbolRefExpr *SymB = Target.getSymB();
const bool CrossSection = SymB &&
&SymA->getSymbol().getSection() != &SymB->getSymbol().getSection();
if (Target.getSymB()) {
const MCSymbol *B = &Target.getSymB()->getSymbol();
MCSymbolData &B_SD = Asm.getSymbolData(*B);
// Offset of the symbol in the section
int64_t a = Layout.getSymbolOffset(&B_SD);
// Ofeset of the relocation in the section
int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
FixedValue = b - a;
// In the case where we have SymbA and SymB, we just need to store the delta
// between the two symbols. Update FixedValue to account for the delta, and
// skip recording the relocation.
if (!CrossSection)
return;
} else {
FixedValue = Target.getConstant();
}
COFFRelocation Reloc;
Reloc.Data.SymbolTableIndex = 0;
Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
// Turn relocations for temporary symbols into section relocations.
if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) {
Reloc.Symb = coff_symbol->Section->Symbol;
FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment)
+ coff_symbol->MCData->getOffset();
} else
Reloc.Symb = coff_symbol;
++Reloc.Symb->Relocations;
Reloc.Data.VirtualAddress += Fixup.getOffset();
Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup,
CrossSection);
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 ||
Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)
FixedValue += 4;
coff_section->Relocations.push_back(Reloc);
}
示例9: RecordRelocation
void AArch64MachObjectWriter::RecordRelocation(
MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {
unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
// See <reloc.h>.
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment);
unsigned Log2Size = 0;
int64_t Value = 0;
unsigned Index = 0;
unsigned Type = 0;
unsigned Kind = Fixup.getKind();
const MCSymbolData *RelSymbol = nullptr;
FixupOffset += Fixup.getOffset();
// AArch64 pcrel relocation addends do not include the section offset.
if (IsPCRel)
FixedValue += FixupOffset;
// ADRP fixups use relocations for the whole symbol value and only
// put the addend in the instruction itself. Clear out any value the
// generic code figured out from the sybmol definition.
if (Kind == AArch64::fixup_aarch64_pcrel_adrp_imm21)
FixedValue = 0;
// imm19 relocations are for conditional branches, which require
// assembler local symbols. If we got here, that's not what we have,
// so complain loudly.
if (Kind == AArch64::fixup_aarch64_pcrel_branch19) {
Asm.getContext().FatalError(Fixup.getLoc(),
"conditional branch requires assembler-local"
" label. '" +
Target.getSymA()->getSymbol().getName() +
"' is external.");
return;
}
// 14-bit branch relocations should only target internal labels, and so
// should never get here.
if (Kind == AArch64::fixup_aarch64_pcrel_branch14) {
Asm.getContext().FatalError(Fixup.getLoc(),
"Invalid relocation on conditional branch!");
return;
}
if (!getAArch64FixupKindMachOInfo(Fixup, Type, Target.getSymA(), Log2Size,
Asm)) {
Asm.getContext().FatalError(Fixup.getLoc(), "unknown AArch64 fixup kind!");
return;
}
Value = Target.getConstant();
if (Target.isAbsolute()) { // constant
// FIXME: Should this always be extern?
// SymbolNum of 0 indicates the absolute section.
Type = MachO::ARM64_RELOC_UNSIGNED;
if (IsPCRel) {
Asm.getContext().FatalError(Fixup.getLoc(),
"PC relative absolute relocation!");
// FIXME: x86_64 sets the type to a branch reloc here. Should we do
// something similar?
}
} else if (Target.getSymB()) { // A - B + constant
const MCSymbol *A = &Target.getSymA()->getSymbol();
const MCSymbolData &A_SD = Asm.getSymbolData(*A);
const MCSymbolData *A_Base = Asm.getAtom(&A_SD);
const MCSymbol *B = &Target.getSymB()->getSymbol();
const MCSymbolData &B_SD = Asm.getSymbolData(*B);
const MCSymbolData *B_Base = Asm.getAtom(&B_SD);
// Check for "[email protected] - .", which comes through here as:
// Ltmp0:
// ... [email protected] - Ltmp0
if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOT &&
Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None &&
Layout.getSymbolOffset(&B_SD) ==
Layout.getFragmentOffset(Fragment) + Fixup.getOffset()) {
// SymB is the PC, so use a PC-rel pointer-to-GOT relocation.
Type = MachO::ARM64_RELOC_POINTER_TO_GOT;
IsPCRel = 1;
MachO::any_relocation_info MRE;
MRE.r_word0 = FixupOffset;
MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
Writer->addRelocation(A_Base, Fragment->getParent(), MRE);
return;
} else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||
Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None)
// Otherwise, neither symbol can be modified.
Asm.getContext().FatalError(Fixup.getLoc(),
"unsupported relocation of modified symbol");
// We don't support PCrel relocations of differences.
if (IsPCRel)
Asm.getContext().FatalError(Fixup.getLoc(),
//.........这里部分代码省略.........
示例10: EvaluateAsRelocatableImpl
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAssembler *Asm,
const MCAsmLayout *Layout,
const SectionAddrMap *Addrs,
bool InSet) const {
++stats::MCExprEvaluate;
switch (getKind()) {
case Target:
return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout);
case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
return true;
case SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
// Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm,
Layout,
Addrs,
true);
// If we failed to simplify this to a constant, let the target
// handle it.
if (Ret && !Res.getSymA() && !Res.getSymB())
return true;
}
Res = MCValue::get(SRE, 0, 0);
return true;
}
case Unary: {
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
Addrs, InSet))
return false;
switch (AUE->getOpcode()) {
case MCUnaryExpr::LNot:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(!Value.getConstant());
break;
case MCUnaryExpr::Minus:
/// -(a - b + const) ==> (b - a - const)
if (Value.getSymA() && !Value.getSymB())
return false;
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
-Value.getConstant());
break;
case MCUnaryExpr::Not:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(~Value.getConstant());
break;
case MCUnaryExpr::Plus:
Res = Value;
break;
}
return true;
}
case Binary: {
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
Addrs, InSet) ||
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
Addrs, InSet))
return false;
// We only support a few operations on non-constant expressions, handle
// those first.
if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) {
switch (ABE->getOpcode()) {
default:
return false;
case MCBinaryExpr::Sub:
// Negate RHS and add.
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
-RHSValue.getConstant(),
Res);
case MCBinaryExpr::Add:
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymA(), RHSValue.getSymB(),
RHSValue.getConstant(),
Res);
}
}
//.........这里部分代码省略.........
示例11: RecordRelocation
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
const MCSymbol *A = &Target.getSymA()->getSymbol();
MCSymbolData &A_SD = Asm.getSymbolData(*A);
MCSectionData const *SectionData = Fragment->getParent();
// Mark this symbol as requiring an entry in the symbol table.
assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() &&
"Section must already have been defined in ExecutePostLayoutBinding!");
assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() &&
"Symbol must already have been defined in ExecutePostLayoutBinding!");
COFFSection *coff_section = SectionMap[&SectionData->getSection()];
COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()];
if (Target.getSymB()) {
if (&Target.getSymA()->getSymbol().getSection()
!= &Target.getSymB()->getSymbol().getSection()) {
llvm_unreachable("Symbol relative relocations are only allowed between "
"symbols in the same section");
}
const MCSymbol *B = &Target.getSymB()->getSymbol();
MCSymbolData &B_SD = Asm.getSymbolData(*B);
FixedValue = Layout.getSymbolOffset(&A_SD) - Layout.getSymbolOffset(&B_SD);
// In the case where we have SymbA and SymB, we just need to store the delta
// between the two symbols. Update FixedValue to account for the delta, and
// skip recording the relocation.
return;
} else {
FixedValue = Target.getConstant();
}
COFFRelocation Reloc;
Reloc.Data.SymbolTableIndex = 0;
Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
// Turn relocations for temporary symbols into section relocations.
if (coff_symbol->MCData->getSymbol().isTemporary()) {
Reloc.Symb = coff_symbol->Section->Symbol;
FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment)
+ coff_symbol->MCData->getOffset();
} else
Reloc.Symb = coff_symbol;
++Reloc.Symb->Relocations;
Reloc.Data.VirtualAddress += Fixup.getOffset();
switch ((unsigned)Fixup.getKind()) {
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_movq_load:
Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_REL32
: COFF::IMAGE_REL_I386_REL32;
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
FixedValue += 4;
break;
case FK_Data_4:
case X86::reloc_signed_4byte:
Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32
: COFF::IMAGE_REL_I386_DIR32;
break;
case FK_Data_8:
if (Is64Bit)
Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64;
else
llvm_unreachable("unsupported relocation type");
break;
default:
llvm_unreachable("unsupported relocation type");
}
coff_section->Relocations.push_back(Reloc);
}
示例12: EvaluateAsRelocatable
bool AsmExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const {
switch (getKind()) {
default:
assert(0 && "Invalid assembly expression kind!");
case Constant:
Res = MCValue::get(cast<AsmConstantExpr>(this)->getValue());
return true;
case SymbolRef: {
MCSymbol *Sym = cast<AsmSymbolRefExpr>(this)->getSymbol();
if (const MCValue *Value = Ctx.GetSymbolValue(Sym))
Res = *Value;
else
Res = MCValue::get(Sym, 0, 0);
return true;
}
case Unary: {
const AsmUnaryExpr *AUE = cast<AsmUnaryExpr>(this);
MCValue Value;
if (!AUE->getSubExpr()->EvaluateAsRelocatable(Ctx, Value))
return false;
switch (AUE->getOpcode()) {
case AsmUnaryExpr::LNot:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(!Value.getConstant());
break;
case AsmUnaryExpr::Minus:
/// -(a - b + const) ==> (b - a - const)
if (Value.getSymA() && !Value.getSymB())
return false;
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
-Value.getConstant());
break;
case AsmUnaryExpr::Not:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(~Value.getConstant());
break;
case AsmUnaryExpr::Plus:
Res = Value;
break;
}
return true;
}
case Binary: {
const AsmBinaryExpr *ABE = cast<AsmBinaryExpr>(this);
MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatable(Ctx, LHSValue) ||
!ABE->getRHS()->EvaluateAsRelocatable(Ctx, RHSValue))
return false;
// We only support a few operations on non-constant expressions, handle
// those first.
if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) {
switch (ABE->getOpcode()) {
default:
return false;
case AsmBinaryExpr::Sub:
// Negate RHS and add.
return EvaluateSymbolicAdd(LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
-RHSValue.getConstant(),
Res);
case AsmBinaryExpr::Add:
return EvaluateSymbolicAdd(LHSValue,
RHSValue.getSymA(), RHSValue.getSymB(),
RHSValue.getConstant(),
Res);
}
}
// FIXME: We need target hooks for the evaluation. It may be limited in
// width, and gas defines the result of comparisons differently from Apple
// as (the result is sign extended).
int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();
int64_t Result = 0;
switch (ABE->getOpcode()) {
case AsmBinaryExpr::Add: Result = LHS + RHS; break;
case AsmBinaryExpr::And: Result = LHS & RHS; break;
case AsmBinaryExpr::Div: Result = LHS / RHS; break;
case AsmBinaryExpr::EQ: Result = LHS == RHS; break;
case AsmBinaryExpr::GT: Result = LHS > RHS; break;
case AsmBinaryExpr::GTE: Result = LHS >= RHS; break;
case AsmBinaryExpr::LAnd: Result = LHS && RHS; break;
case AsmBinaryExpr::LOr: Result = LHS || RHS; break;
case AsmBinaryExpr::LT: Result = LHS < RHS; break;
case AsmBinaryExpr::LTE: Result = LHS <= RHS; break;
case AsmBinaryExpr::Mod: Result = LHS % RHS; break;
case AsmBinaryExpr::Mul: Result = LHS * RHS; break;
case AsmBinaryExpr::NE: Result = LHS != RHS; break;
case AsmBinaryExpr::Or: Result = LHS | RHS; break;
//.........这里部分代码省略.........
示例13: RecordRelocation
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
bool &IsPCRel,
uint64_t &FixedValue) {
assert(Target.getSymA() && "Relocation must reference a symbol!");
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
const MCSymbol &A = Symbol.AliasedSymbol();
if (!Asm.hasSymbolData(A))
Asm.getContext().FatalError(
Fixup.getLoc(),
Twine("symbol '") + A.getName() + "' can not be undefined");
const MCSymbolData &A_SD = Asm.getSymbolData(A);
MCSectionData const *SectionData = Fragment->getParent();
// Mark this symbol as requiring an entry in the symbol table.
assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() &&
"Section must already have been defined in ExecutePostLayoutBinding!");
assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() &&
"Symbol must already have been defined in ExecutePostLayoutBinding!");
COFFSection *coff_section = SectionMap[&SectionData->getSection()];
COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()];
const MCSymbolRefExpr *SymB = Target.getSymB();
bool CrossSection = false;
if (SymB) {
const MCSymbol *B = &SymB->getSymbol();
const MCSymbolData &B_SD = Asm.getSymbolData(*B);
if (!B_SD.getFragment())
Asm.getContext().FatalError(
Fixup.getLoc(),
Twine("symbol '") + B->getName() +
"' can not be undefined in a subtraction expression");
if (!A_SD.getFragment())
Asm.getContext().FatalError(
Fixup.getLoc(),
Twine("symbol '") + Symbol.getName() +
"' can not be undefined in a subtraction expression");
CrossSection = &Symbol.getSection() != &B->getSection();
// Offset of the symbol in the section
int64_t a = Layout.getSymbolOffset(&B_SD);
// Ofeset of the relocation in the section
int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
FixedValue = b - a;
// In the case where we have SymbA and SymB, we just need to store the delta
// between the two symbols. Update FixedValue to account for the delta, and
// skip recording the relocation.
if (!CrossSection)
return;
} else {
FixedValue = Target.getConstant();
}
COFFRelocation Reloc;
Reloc.Data.SymbolTableIndex = 0;
Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
// Turn relocations for temporary symbols into section relocations.
if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) {
Reloc.Symb = coff_symbol->Section->Symbol;
FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment)
+ coff_symbol->MCData->getOffset();
} else
Reloc.Symb = coff_symbol;
++Reloc.Symb->Relocations;
Reloc.Data.VirtualAddress += Fixup.getOffset();
Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup,
CrossSection);
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
(Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32))
FixedValue += 4;
if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
switch (Reloc.Data.Type) {
case COFF::IMAGE_REL_ARM_ABSOLUTE:
case COFF::IMAGE_REL_ARM_ADDR32:
case COFF::IMAGE_REL_ARM_ADDR32NB:
case COFF::IMAGE_REL_ARM_TOKEN:
case COFF::IMAGE_REL_ARM_SECTION:
case COFF::IMAGE_REL_ARM_SECREL:
break;
//.........这里部分代码省略.........
示例14: RecordTLVPRelocation
void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,
const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
uint64_t &FixedValue) {
unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
// If this is a 32-bit TLVP reloc it's handled a bit differently.
if (Target.getSymA() &&
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) {
RecordTLVPRelocation(Writer, Asm, Layout, Fragment, Fixup, Target,
FixedValue);
return;
}
// If this is a difference or a defined symbol plus an offset, then we need a
// scattered relocation entry. Differences always require scattered
// relocations.
if (Target.getSymB()) {
RecordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
Target, Log2Size, FixedValue);
return;
}
// Get the symbol data, if any.
const MCSymbolData *SD = nullptr;
if (Target.getSymA())
SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
// If this is an internal relocation with an offset, it also needs a scattered
// relocation entry.
uint32_t Offset = Target.getConstant();
if (IsPCRel)
Offset += 1 << Log2Size;
// Try to record the scattered relocation if needed. Fall back to non
// scattered if necessary (see comments in RecordScatteredRelocation()
// for details).
if (Offset && SD && !Writer->doesSymbolRequireExternRelocation(SD) &&
RecordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
Target, Log2Size, FixedValue))
return;
// See <reloc.h>.
uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
unsigned Index = 0;
unsigned Type = 0;
const MCSymbol *RelSymbol = nullptr;
if (Target.isAbsolute()) { // constant
// SymbolNum of 0 indicates the absolute section.
//
// FIXME: Currently, these are never generated (see code below). I cannot
// find a case where they are actually emitted.
Type = MachO::GENERIC_RELOC_VANILLA;
} else {
// Resolve constant variables.
if (SD->getSymbol().isVariable()) {
int64_t Res;
if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute(
Res, Layout, Writer->getSectionAddressMap())) {
FixedValue = Res;
return;
}
}
// Check whether we need an external or internal relocation.
if (Writer->doesSymbolRequireExternRelocation(SD)) {
RelSymbol = &SD->getSymbol();
// For external relocations, make sure to offset the fixup value to
// compensate for the addend of the symbol address, if it was
// undefined. This occurs with weak definitions, for example.
if (!SD->getSymbol().isUndefined())
FixedValue -= Layout.getSymbolOffset(SD);
} else {
// The index is the section ordinal (1-based).
const MCSectionData &SymSD = Asm.getSectionData(
SD->getSymbol().getSection());
Index = SymSD.getOrdinal() + 1;
FixedValue += Writer->getSectionAddress(&SymSD);
}
if (IsPCRel)
FixedValue -= Writer->getSectionAddress(Fragment->getParent());
Type = MachO::GENERIC_RELOC_VANILLA;
}
// struct relocation_info (8 bytes)
MachO::any_relocation_info MRE;
MRE.r_word0 = FixupOffset;
MRE.r_word1 =
(Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
}
示例15: EvaluateAsRelocatable
bool MCExpr::EvaluateAsRelocatable(MCValue &Res) const {
switch (getKind()) {
case Target:
return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res);
case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
return true;
case SymbolRef: {
const MCSymbol &Sym = cast<MCSymbolRefExpr>(this)->getSymbol();
// Evaluate recursively if this is a variable.
if (Sym.isVariable())
return Sym.getValue()->EvaluateAsRelocatable(Res);
Res = MCValue::get(&Sym, 0, 0);
return true;
}
case Unary: {
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
if (!AUE->getSubExpr()->EvaluateAsRelocatable(Value))
return false;
switch (AUE->getOpcode()) {
case MCUnaryExpr::LNot:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(!Value.getConstant());
break;
case MCUnaryExpr::Minus:
/// -(a - b + const) ==> (b - a - const)
if (Value.getSymA() && !Value.getSymB())
return false;
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
-Value.getConstant());
break;
case MCUnaryExpr::Not:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(~Value.getConstant());
break;
case MCUnaryExpr::Plus:
Res = Value;
break;
}
return true;
}
case Binary: {
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatable(LHSValue) ||
!ABE->getRHS()->EvaluateAsRelocatable(RHSValue))
return false;
// We only support a few operations on non-constant expressions, handle
// those first.
if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) {
switch (ABE->getOpcode()) {
default:
return false;
case MCBinaryExpr::Sub:
// Negate RHS and add.
return EvaluateSymbolicAdd(LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
-RHSValue.getConstant(),
Res);
case MCBinaryExpr::Add:
return EvaluateSymbolicAdd(LHSValue,
RHSValue.getSymA(), RHSValue.getSymB(),
RHSValue.getConstant(),
Res);
}
}
// FIXME: We need target hooks for the evaluation. It may be limited in
// width, and gas defines the result of comparisons and right shifts
// differently from Apple as.
int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();
int64_t Result = 0;
switch (ABE->getOpcode()) {
case MCBinaryExpr::Add: Result = LHS + RHS; break;
case MCBinaryExpr::And: Result = LHS & RHS; break;
case MCBinaryExpr::Div: Result = LHS / RHS; break;
case MCBinaryExpr::EQ: Result = LHS == RHS; break;
case MCBinaryExpr::GT: Result = LHS > RHS; break;
case MCBinaryExpr::GTE: Result = LHS >= RHS; break;
case MCBinaryExpr::LAnd: Result = LHS && RHS; break;
case MCBinaryExpr::LOr: Result = LHS || RHS; break;
case MCBinaryExpr::LT: Result = LHS < RHS; break;
case MCBinaryExpr::LTE: Result = LHS <= RHS; break;
case MCBinaryExpr::Mod: Result = LHS % RHS; break;
case MCBinaryExpr::Mul: Result = LHS * RHS; break;
//.........这里部分代码省略.........