diff options
| author | Jim Grosbach <grosbach@apple.com> | 2012-09-13 23:11:25 +0000 |
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2012-09-13 23:11:25 +0000 |
| commit | d96ef194d97a905907eec4f21cf771108c5087aa (patch) | |
| tree | 7d1ede2275a658bd56ae773caadcf978116d275a | |
| parent | 058049cdea6089bdc025b42e6a370e8cef45d142 (diff) | |
| download | bcm5719-llvm-d96ef194d97a905907eec4f21cf771108c5087aa.tar.gz bcm5719-llvm-d96ef194d97a905907eec4f21cf771108c5087aa.zip | |
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
llvm-svn: 163853
| -rw-r--r-- | llvm/include/llvm/MC/MCMachObjectWriter.h | 2 | ||||
| -rw-r--r-- | llvm/lib/MC/MachObjectWriter.cpp | 35 |
2 files changed, 32 insertions, 5 deletions
diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h index 949d90700e0..da3b2491018 100644 --- a/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -233,6 +233,8 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); + void markAbsoluteVariableSymbols(MCAssembler &Asm, + const MCAsmLayout &Layout); void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index c57b0d65c1d..904fbbfe83e 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/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); |

