aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/MachObjectWriter.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-09-13 23:11:25 +0000
committerJim Grosbach <grosbach@apple.com>2012-09-13 23:11:25 +0000
commit45d81bdde87a38c21facf2ec3b82b0589e9de7e9 (patch)
tree1a34686bf98e38228f2d860457a4ce18946a38cf /lib/MC/MachObjectWriter.cpp
parentb998913ff4aa58c3c342e167c785029cb331078e (diff)
downloadexternal_llvm-45d81bdde87a38c21facf2ec3b82b0589e9de7e9.zip
external_llvm-45d81bdde87a38c21facf2ec3b82b0589e9de7e9.tar.gz
external_llvm-45d81bdde87a38c21facf2ec3b82b0589e9de7e9.tar.bz2
MachO: Correctly mark symbol-difference variables as N_ABS.
.set a, b - c + CONSTANT d = b - c + CONSTANT Both 'a' and 'd' should be marked as absolute symbols (N_ABS). rdar://12219394 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163853 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MachObjectWriter.cpp')
-rw-r--r--lib/MC/MachObjectWriter.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index c57b0d6..904fbbf 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -68,6 +68,11 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
// 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 '" +
@@ -315,11 +320,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
// Compute the symbol address.
if (Symbol.isDefined()) {
- if (Symbol.isAbsolute()) {
- Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
- } else {
- Address = getSymbolAddress(&Data, Layout);
- }
+ Address = getSymbolAddress(&Data, Layout);
} else if (Data.isCommon()) {
// Common symbols are encoded with the size in the address
// field, and their alignment in the flags.
@@ -557,6 +558,26 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
}
}
+void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ for (MCAssembler::symbol_iterator i = Asm.symbol_begin(),
+ e = Asm.symbol_end();
+ i != e; ++i) {
+ MCSymbolData &SD = *i;
+ if (!SD.getSymbol().isVariable())
+ continue;
+
+ // Is the variable is a symbol difference (SA - SB + C) expression,
+ // and neither symbol is external, mark the variable as absolute.
+ const MCExpr *Expr = SD.getSymbol().getVariableValue();
+ MCValue Value;
+ if (Expr->EvaluateAsRelocatable(Value, Layout)) {
+ if (Value.getSymA() && Value.getSymB())
+ const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
+ }
+ }
+}
+
void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
computeSectionAddresses(Asm, Layout);
@@ -564,6 +585,10 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
// Create symbol data for any indirect symbols.
BindIndirectSymbols(Asm);
+ // Mark symbol difference expressions in variables (from .set or = directives)
+ // as absolute.
+ markAbsoluteVariableSymbols(Asm, Layout);
+
// Compute symbol table information and bind symbol indices.
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
UndefinedSymbolData);