@@ -384,11 +384,26 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
384
384
const MCFragment *Fragment,
385
385
const MCFixup &Fixup, MCValue Target,
386
386
uint64_t &FixedValue) {
387
-
388
- if (Target.getSymB ())
389
- report_fatal_error (" Handling Target.SymB for relocation is unimplemented." );
390
-
391
- const MCSymbol &SymA = Target.getSymA ()->getSymbol ();
387
+ auto getIndex = [this ](const MCSymbol *Sym,
388
+ const MCSectionXCOFF *ContainingCsect) {
389
+ // If we could not find the symbol directly in SymbolIndexMap, this symbol
390
+ // could either be a temporary symbol or an undefined symbol. In this case,
391
+ // we would need to have the relocation reference its csect instead.
392
+ return SymbolIndexMap.find (Sym) != SymbolIndexMap.end ()
393
+ ? SymbolIndexMap[Sym]
394
+ : SymbolIndexMap[ContainingCsect->getQualNameSymbol ()];
395
+ };
396
+
397
+ auto getVirtualAddress = [this ,
398
+ &Layout](const MCSymbol *Sym,
399
+ const MCSectionXCOFF *ContainingCsect) {
400
+ // If Sym is a csect, return csect's address.
401
+ // If Sym is a label, return csect's address + label's offset from the csect.
402
+ return SectionMap[ContainingCsect]->Address +
403
+ (Sym->isDefined () ? Layout.getSymbolOffset (*Sym) : 0 );
404
+ };
405
+
406
+ const MCSymbol *const SymA = &Target.getSymA ()->getSymbol ();
392
407
393
408
MCAsmBackend &Backend = Asm.getBackend ();
394
409
bool IsPCRel = Backend.getFixupKindInfo (Fixup.getKind ()).Flags &
@@ -399,26 +414,15 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
399
414
std::tie (Type, SignAndSize) =
400
415
TargetObjectWriter->getRelocTypeAndSignSize (Target, Fixup, IsPCRel);
401
416
402
- const MCSectionXCOFF *SymASec =
403
- getContainingCsect (cast<MCSymbolXCOFF>(&SymA));
417
+ const MCSectionXCOFF *SymASec = getContainingCsect (cast<MCSymbolXCOFF>(SymA));
404
418
assert (SectionMap.find (SymASec) != SectionMap.end () &&
405
419
" Expected containing csect to exist in map." );
406
420
407
- // If we could not find SymA directly in SymbolIndexMap, this symbol could
408
- // either be a temporary symbol or an undefined symbol. In this case, we
409
- // would need to have the relocation reference its csect instead.
410
- uint32_t Index = SymbolIndexMap.find (&SymA) != SymbolIndexMap.end ()
411
- ? SymbolIndexMap[&SymA]
412
- : SymbolIndexMap[SymASec->getQualNameSymbol ()];
413
-
421
+ const uint32_t Index = getIndex (SymA, SymASec);
414
422
if (Type == XCOFF::RelocationType::R_POS)
415
423
// The FixedValue should be symbol's virtual address in this object file
416
424
// plus any constant value that we might get.
417
- // Notice that SymA.isDefined() could return false, but SymASec could still
418
- // be a defined csect. One of the example is the TOC-base symbol.
419
- FixedValue = SectionMap[SymASec]->Address +
420
- (SymA.isDefined () ? Layout.getSymbolOffset (SymA) : 0 ) +
421
- Target.getConstant ();
425
+ FixedValue = getVirtualAddress (SymA, SymASec) + Target.getConstant ();
422
426
else if (Type == XCOFF::RelocationType::R_TOC)
423
427
// The FixedValue should be the TC entry offset from TOC-base.
424
428
FixedValue = SectionMap[SymASec]->Address - TOCCsects.front ().Address ;
@@ -435,6 +439,33 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
435
439
assert (SectionMap.find (RelocationSec) != SectionMap.end () &&
436
440
" Expected containing csect to exist in map." );
437
441
SectionMap[RelocationSec]->Relocations .push_back (Reloc);
442
+
443
+ if (!Target.getSymB ())
444
+ return ;
445
+
446
+ const MCSymbol *const SymB = &Target.getSymB ()->getSymbol ();
447
+ if (SymA == SymB)
448
+ report_fatal_error (" relocation for opposite term is not yet supported" );
449
+
450
+ const MCSectionXCOFF *SymBSec = getContainingCsect (cast<MCSymbolXCOFF>(SymB));
451
+ assert (SectionMap.find (SymBSec) != SectionMap.end () &&
452
+ " Expected containing csect to exist in map." );
453
+ if (SymASec == SymBSec)
454
+ report_fatal_error (
455
+ " relocation for paired relocatable term is not yet supported" );
456
+
457
+ assert (Type == XCOFF::RelocationType::R_POS &&
458
+ " SymA must be R_POS here if it's not opposite term or paired "
459
+ " relocatable term." );
460
+ const uint32_t IndexB = getIndex (SymB, SymBSec);
461
+ // SymB must be R_NEG here, given the general form of Target(MCValue) is
462
+ // "SymbolA - SymbolB + imm64".
463
+ const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
464
+ XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
465
+ SectionMap[RelocationSec]->Relocations .push_back (RelocB);
466
+ // We already folded "SymbolA + imm64" above when Type is R_POS for SymbolA,
467
+ // now we just need to fold "- SymbolB" here.
468
+ FixedValue -= getVirtualAddress (SymB, SymBSec);
438
469
}
439
470
440
471
void XCOFFObjectWriter::writeSections (const MCAssembler &Asm,
0 commit comments