X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMachObjectWriter.cpp;h=61df5bb35c761b234c6d31628bf97bb9deee5a80;hb=cecbc3d28277ff4916326311cbf87335ed05d106;hp=689aabc333df71f4ac6152826612686ec7055b92;hpb=a8c02c3bdd68e65d14fb6b0d56989663754059b0;p=oota-llvm.git diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 689aabc333d..61df5bb35c7 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -616,22 +616,32 @@ public: if (IsPCRel) report_fatal_error("unsupported pc-relative relocation of difference"); - // We don't currently support any situation where one or both of the - // symbols would require a local relocation. This is almost certainly - // unused and may not be possible to encode correctly. - if (!A_Base || !B_Base) - report_fatal_error("unsupported local relocations in difference"); + // The support for the situation where one or both of the symbols would + // require a local relocation is handled just like if the symbols were + // external. This is certainly used in the case of debug sections where + // the section has only temporary symbols and thus the symbols don't have + // base symbols. This is encoded using the section ordinal and + // non-extern relocation entries. // Darwin 'as' doesn't emit correct relocations for this (it ends up with - // a single SIGNED relocation); reject it for now. - if (A_Base == B_Base) + // a single SIGNED relocation); reject it for now. Except the case where + // both symbols don't have a base, equal but both NULL. + if (A_Base == B_Base && A_Base) report_fatal_error("unsupported relocation with identical base"); - Value += Layout.getSymbolAddress(&A_SD) - Layout.getSymbolAddress(A_Base); - Value -= Layout.getSymbolAddress(&B_SD) - Layout.getSymbolAddress(B_Base); + Value += Layout.getSymbolAddress(&A_SD) - + (A_Base == NULL ? 0 : Layout.getSymbolAddress(A_Base)); + Value -= Layout.getSymbolAddress(&B_SD) - + (B_Base == NULL ? 0 : Layout.getSymbolAddress(B_Base)); - Index = A_Base->getIndex(); - IsExtern = 1; + if (A_Base) { + Index = A_Base->getIndex(); + IsExtern = 1; + } + else { + Index = A_SD.getFragment()->getParent()->getOrdinal() + 1; + IsExtern = 0; + } Type = RIT_X86_64_Unsigned; MachRelocationEntry MRE; @@ -643,8 +653,14 @@ public: (Type << 28)); Relocations[Fragment->getParent()].push_back(MRE); - Index = B_Base->getIndex(); - IsExtern = 1; + if (B_Base) { + Index = B_Base->getIndex(); + IsExtern = 1; + } + else { + Index = B_SD.getFragment()->getParent()->getOrdinal() + 1; + IsExtern = 0; + } Type = RIT_X86_64_Subtractor; } else { const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); @@ -1344,7 +1360,7 @@ bool MachObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, IsPCRel, DF); } -void MachObjectWriter::WriteObject(const MCAssembler &Asm, +void MachObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { ((MachObjectWriterImpl*) Impl)->WriteObject(Asm, Layout); }