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
This commit is contained in:
Jim Grosbach 2012-09-13 23:11:25 +00:00
parent b998913ff4
commit 45d81bdde8
2 changed files with 32 additions and 5 deletions

View File

@ -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,

View File

@ -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);