diff options
Diffstat (limited to 'lib/MC/MachObjectWriter.cpp')
-rw-r--r-- | lib/MC/MachObjectWriter.cpp | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 5820a22..a94b214 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 '" + @@ -140,8 +145,8 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands, /// WriteSegmentLoadCommand - Write a segment load command. /// -/// \arg NumSections - The number of sections in this segment. -/// \arg SectionDataSize - The total size of the sections. +/// \param NumSections The number of sections in this segment. +/// \param SectionDataSize The total size of the sections. void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, @@ -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. @@ -396,8 +397,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { continue; // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; + IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); Asm.getOrCreateSymbolData(*it->Symbol); } @@ -414,8 +414,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { continue; // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; + IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); // Set the symbol type to undefined lazy, but only on construction. // @@ -559,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); @@ -566,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); @@ -797,8 +820,12 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, it = Asm.data_region_begin(), ie = Asm.data_region_end(); it != ie; ++it) { const DataRegionData *Data = &(*it); - uint64_t Start = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), Layout); - uint64_t End = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), Layout); + uint64_t Start = + getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), + Layout); + uint64_t End = + getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), + Layout); DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind << " start: " << Start << "(" << Data->Start->getName() << ")" << " end: " << End << "(" << Data->End->getName() << ")" |