mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-10 04:24:23 +00:00
Provide a version of getSymbolOffset that returns false on error.
This simplifies ELFObjectWriter::SymbolValue a bit more. This new version will also be used in the COFF writer to fix pr19147. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207711 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b861d48f79
commit
593cb79eb5
@ -102,6 +102,10 @@ public:
|
|||||||
|
|
||||||
/// \brief Get the offset of the given symbol, as computed in the current
|
/// \brief Get the offset of the given symbol, as computed in the current
|
||||||
/// layout.
|
/// layout.
|
||||||
|
/// \result True on success.
|
||||||
|
bool getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const;
|
||||||
|
|
||||||
|
/// \brief Variant that reports a fatal error if the offset is not computable.
|
||||||
uint64_t getSymbolOffset(const MCSymbolData *SD) const;
|
uint64_t getSymbolOffset(const MCSymbolData *SD) const;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -486,34 +486,16 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
|
|||||||
Write16(ShstrtabIndex);
|
Write16(ShstrtabIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
|
uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
MCSymbolData *Data = &OrigData;
|
if (Data.isCommon() && Data.isExternal())
|
||||||
if (Data->isCommon() && Data->isExternal())
|
return Data.getCommonAlignment();
|
||||||
return Data->getCommonAlignment();
|
|
||||||
|
|
||||||
const MCSymbol *Symbol = &Data->getSymbol();
|
uint64_t Res;
|
||||||
MCAssembler &Asm = Layout.getAssembler();
|
if (!Layout.getSymbolOffset(&Data, Res))
|
||||||
bool IsThumb = Asm.isThumbFunc(Symbol);
|
|
||||||
|
|
||||||
// Given how we implement symver, we can end up with an symbol reference
|
|
||||||
// to an undefined symbol. Walk past it first.
|
|
||||||
if (Symbol->isVariable()) {
|
|
||||||
const MCExpr *Expr = Symbol->getVariableValue();
|
|
||||||
if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
|
||||||
if (Ref->getKind() == MCSymbolRefExpr::VK_None) {
|
|
||||||
Symbol = &Ref->getSymbol();
|
|
||||||
Data = &Asm.getOrCreateSymbolData(*Symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Symbol->isVariable() && !Data->getFragment())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint64_t Res = Layout.getSymbolOffset(Data);
|
if (Layout.getAssembler().isThumbFunc(&Data.getSymbol()))
|
||||||
|
|
||||||
if (IsThumb)
|
|
||||||
Res |= 1;
|
Res |= 1;
|
||||||
|
|
||||||
return Res;
|
return Res;
|
||||||
|
@ -118,37 +118,66 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Simple getSymbolOffset helper for the non-varibale case.
|
// Simple getSymbolOffset helper for the non-varibale case.
|
||||||
static uint64_t getLabelOffset(const MCAsmLayout &Layout,
|
static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD,
|
||||||
const MCSymbolData &SD) {
|
bool ReportError, uint64_t &Val) {
|
||||||
if (!SD.getFragment())
|
if (!SD.getFragment()) {
|
||||||
report_fatal_error("unable to evaluate offset to undefined symbol '" +
|
if (ReportError)
|
||||||
SD.getSymbol().getName() + "'");
|
report_fatal_error("unable to evaluate offset to undefined symbol '" +
|
||||||
return Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
|
SD.getSymbol().getName() + "'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
|
static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
|
||||||
|
const MCSymbolData *SD, bool ReportError,
|
||||||
|
uint64_t &Val) {
|
||||||
const MCSymbol &S = SD->getSymbol();
|
const MCSymbol &S = SD->getSymbol();
|
||||||
|
|
||||||
if (!S.isVariable())
|
if (!S.isVariable())
|
||||||
return getLabelOffset(*this, *SD);
|
return getLabelOffset(Layout, *SD, ReportError, Val);
|
||||||
|
|
||||||
// If SD is a variable, evaluate it.
|
// If SD is a variable, evaluate it.
|
||||||
MCValue Target;
|
MCValue Target;
|
||||||
if (!S.getVariableValue()->EvaluateAsValue(Target, this))
|
if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
|
||||||
report_fatal_error("unable to evaluate offset for variable '" +
|
report_fatal_error("unable to evaluate offset for variable '" +
|
||||||
S.getName() + "'");
|
S.getName() + "'");
|
||||||
|
|
||||||
uint64_t Offset = Target.getConstant();
|
uint64_t Offset = Target.getConstant();
|
||||||
|
|
||||||
|
const MCAssembler &Asm = Layout.getAssembler();
|
||||||
|
|
||||||
const MCSymbolRefExpr *A = Target.getSymA();
|
const MCSymbolRefExpr *A = Target.getSymA();
|
||||||
if (A)
|
if (A) {
|
||||||
Offset += getLabelOffset(*this, Assembler.getSymbolData(A->getSymbol()));
|
uint64_t ValA;
|
||||||
|
if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError,
|
||||||
|
ValA))
|
||||||
|
return false;
|
||||||
|
Offset += ValA;
|
||||||
|
}
|
||||||
|
|
||||||
const MCSymbolRefExpr *B = Target.getSymB();
|
const MCSymbolRefExpr *B = Target.getSymB();
|
||||||
if (B)
|
if (B) {
|
||||||
Offset -= getLabelOffset(*this, Assembler.getSymbolData(B->getSymbol()));
|
uint64_t ValB;
|
||||||
|
if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError,
|
||||||
|
ValB))
|
||||||
|
return false;
|
||||||
|
Offset -= ValB;
|
||||||
|
}
|
||||||
|
|
||||||
return Offset;
|
Val = Offset;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const {
|
||||||
|
return getSymbolOffsetImpl(*this, SD, false, Val);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
|
||||||
|
uint64_t Val;
|
||||||
|
getSymbolOffsetImpl(*this, SD, true, Val);
|
||||||
|
return Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
|
uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user