forked from OSchip/llvm-project
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
This commit is contained in:
parent
058049cdea
commit
d96ef194d9
|
@ -233,6 +233,8 @@ public:
|
||||||
void computeSectionAddresses(const MCAssembler &Asm,
|
void computeSectionAddresses(const MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout);
|
const MCAsmLayout &Layout);
|
||||||
|
|
||||||
|
void markAbsoluteVariableSymbols(MCAssembler &Asm,
|
||||||
|
const MCAsmLayout &Layout);
|
||||||
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
|
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
|
||||||
|
|
||||||
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
|
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
|
||||||
|
|
|
@ -68,6 +68,11 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
|
||||||
|
|
||||||
// If this is a variable, then recursively evaluate now.
|
// If this is a variable, then recursively evaluate now.
|
||||||
if (S.isVariable()) {
|
if (S.isVariable()) {
|
||||||
|
if (const MCConstantExpr *C =
|
||||||
|
dyn_cast<const MCConstantExpr>(S.getVariableValue()))
|
||||||
|
return C->getValue();
|
||||||
|
|
||||||
|
|
||||||
MCValue Target;
|
MCValue Target;
|
||||||
if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
|
if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
|
||||||
report_fatal_error("unable to evaluate offset for variable '" +
|
report_fatal_error("unable to evaluate offset for variable '" +
|
||||||
|
@ -315,11 +320,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
|
||||||
|
|
||||||
// Compute the symbol address.
|
// Compute the symbol address.
|
||||||
if (Symbol.isDefined()) {
|
if (Symbol.isDefined()) {
|
||||||
if (Symbol.isAbsolute()) {
|
Address = getSymbolAddress(&Data, Layout);
|
||||||
Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
|
|
||||||
} else {
|
|
||||||
Address = getSymbolAddress(&Data, Layout);
|
|
||||||
}
|
|
||||||
} else if (Data.isCommon()) {
|
} else if (Data.isCommon()) {
|
||||||
// Common symbols are encoded with the size in the address
|
// Common symbols are encoded with the size in the address
|
||||||
// field, and their alignment in the flags.
|
// 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,
|
void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
computeSectionAddresses(Asm, Layout);
|
computeSectionAddresses(Asm, Layout);
|
||||||
|
@ -564,6 +585,10 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||||
// Create symbol data for any indirect symbols.
|
// Create symbol data for any indirect symbols.
|
||||||
BindIndirectSymbols(Asm);
|
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.
|
// Compute symbol table information and bind symbol indices.
|
||||||
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
|
||||||
UndefinedSymbolData);
|
UndefinedSymbolData);
|
||||||
|
|
Loading…
Reference in New Issue