summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-04-30 21:51:13 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-04-30 21:51:13 +0000
commit593cb79eb5517d821248ba0698f35e0a6e65b6e4 (patch)
tree7521045d1983438cd46d2b57897932755aefa09b /lib/MC
parentb861d48f798bc772be99df66d40727c80d3da1dd (diff)
downloadllvm-593cb79eb5517d821248ba0698f35e0a6e65b6e4.tar.gz
llvm-593cb79eb5517d821248ba0698f35e0a6e65b6e4.tar.bz2
llvm-593cb79eb5517d821248ba0698f35e0a6e65b6e4.tar.xz
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
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/ELFObjectWriter.cpp30
-rw-r--r--lib/MC/MCAssembler.cpp57
2 files changed, 49 insertions, 38 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 27e34da632..9c224b3da6 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -486,34 +486,16 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
Write16(ShstrtabIndex);
}
-uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
+uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
const MCAsmLayout &Layout) {
- MCSymbolData *Data = &OrigData;
- if (Data->isCommon() && Data->isExternal())
- return Data->getCommonAlignment();
-
- const MCSymbol *Symbol = &Data->getSymbol();
- MCAssembler &Asm = Layout.getAssembler();
- 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 (Data.isCommon() && Data.isExternal())
+ return Data.getCommonAlignment();
- if (!Symbol->isVariable() && !Data->getFragment())
+ uint64_t Res;
+ if (!Layout.getSymbolOffset(&Data, Res))
return 0;
- uint64_t Res = Layout.getSymbolOffset(Data);
-
- if (IsThumb)
+ if (Layout.getAssembler().isThumbFunc(&Data.getSymbol()))
Res |= 1;
return Res;
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index a96e4ba151..c65e44e531 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -118,37 +118,66 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
}
// Simple getSymbolOffset helper for the non-varibale case.
-static uint64_t getLabelOffset(const MCAsmLayout &Layout,
- const MCSymbolData &SD) {
- if (!SD.getFragment())
- report_fatal_error("unable to evaluate offset to undefined symbol '" +
- SD.getSymbol().getName() + "'");
- return Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
+static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD,
+ bool ReportError, uint64_t &Val) {
+ if (!SD.getFragment()) {
+ if (ReportError)
+ report_fatal_error("unable to evaluate offset to undefined symbol '" +
+ 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();
if (!S.isVariable())
- return getLabelOffset(*this, *SD);
+ return getLabelOffset(Layout, *SD, ReportError, Val);
// If SD is a variable, evaluate it.
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsValue(Target, this))
+ if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
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)
- Offset += getLabelOffset(*this, Assembler.getSymbolData(A->getSymbol()));
+ 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)
- Offset -= getLabelOffset(*this, Assembler.getSymbolData(B->getSymbol()));
+ if (B) {
+ uint64_t ValB;
+ if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError,
+ ValB))
+ return false;
+ Offset -= ValB;
+ }
+
+ Val = Offset;
+ return true;
+}
- return Offset;
+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 {