Skip to content

Commit

Permalink
[XCOFF][AIX] Relocation support for SymB
Browse files Browse the repository at this point in the history
This patch intends to provide relocation support for the expression
 contains two unpaired relocatable terms with opposite signs.

Differential Revision: https://reviews.llvm.org/D77424
  • Loading branch information
jasonliudev committed Apr 15, 2020
1 parent 4578fa8 commit c3c67e9
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 19 deletions.
69 changes: 50 additions & 19 deletions llvm/lib/MC/XCOFFObjectWriter.cpp
Expand Up @@ -384,11 +384,26 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {

if (Target.getSymB())
report_fatal_error("Handling Target.SymB for relocation is unimplemented.");

const MCSymbol &SymA = Target.getSymA()->getSymbol();
auto getIndex = [this](const MCSymbol *Sym,
const MCSectionXCOFF *ContainingCsect) {
// If we could not find the symbol directly in SymbolIndexMap, this symbol
// could either be a temporary symbol or an undefined symbol. In this case,
// we would need to have the relocation reference its csect instead.
return SymbolIndexMap.find(Sym) != SymbolIndexMap.end()
? SymbolIndexMap[Sym]
: SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
};

auto getVirtualAddress = [this,
&Layout](const MCSymbol *Sym,
const MCSectionXCOFF *ContainingCsect) {
// If Sym is a csect, return csect's address.
// If Sym is a label, return csect's address + label's offset from the csect.
return SectionMap[ContainingCsect]->Address +
(Sym->isDefined() ? Layout.getSymbolOffset(*Sym) : 0);
};

const MCSymbol *const SymA = &Target.getSymA()->getSymbol();

MCAsmBackend &Backend = Asm.getBackend();
bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
Expand All @@ -399,26 +414,15 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
std::tie(Type, SignAndSize) =
TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);

const MCSectionXCOFF *SymASec =
getContainingCsect(cast<MCSymbolXCOFF>(&SymA));
const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
assert(SectionMap.find(SymASec) != SectionMap.end() &&
"Expected containing csect to exist in map.");

// If we could not find SymA directly in SymbolIndexMap, this symbol could
// either be a temporary symbol or an undefined symbol. In this case, we
// would need to have the relocation reference its csect instead.
uint32_t Index = SymbolIndexMap.find(&SymA) != SymbolIndexMap.end()
? SymbolIndexMap[&SymA]
: SymbolIndexMap[SymASec->getQualNameSymbol()];

const uint32_t Index = getIndex(SymA, SymASec);
if (Type == XCOFF::RelocationType::R_POS)
// The FixedValue should be symbol's virtual address in this object file
// plus any constant value that we might get.
// Notice that SymA.isDefined() could return false, but SymASec could still
// be a defined csect. One of the example is the TOC-base symbol.
FixedValue = SectionMap[SymASec]->Address +
(SymA.isDefined() ? Layout.getSymbolOffset(SymA) : 0) +
Target.getConstant();
FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
else if (Type == XCOFF::RelocationType::R_TOC)
// The FixedValue should be the TC entry offset from TOC-base.
FixedValue = SectionMap[SymASec]->Address - TOCCsects.front().Address;
Expand All @@ -435,6 +439,33 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
assert(SectionMap.find(RelocationSec) != SectionMap.end() &&
"Expected containing csect to exist in map.");
SectionMap[RelocationSec]->Relocations.push_back(Reloc);

if (!Target.getSymB())
return;

const MCSymbol *const SymB = &Target.getSymB()->getSymbol();
if (SymA == SymB)
report_fatal_error("relocation for opposite term is not yet supported");

const MCSectionXCOFF *SymBSec = getContainingCsect(cast<MCSymbolXCOFF>(SymB));
assert(SectionMap.find(SymBSec) != SectionMap.end() &&
"Expected containing csect to exist in map.");
if (SymASec == SymBSec)
report_fatal_error(
"relocation for paired relocatable term is not yet supported");

assert(Type == XCOFF::RelocationType::R_POS &&
"SymA must be R_POS here if it's not opposite term or paired "
"relocatable term.");
const uint32_t IndexB = getIndex(SymB, SymBSec);
// SymB must be R_NEG here, given the general form of Target(MCValue) is
// "SymbolA - SymbolB + imm64".
const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
SectionMap[RelocationSec]->Relocations.push_back(RelocB);
// We already folded "SymbolA + imm64" above when Type is R_POS for SymbolA,
// now we just need to fold "- SymbolB" here.
FixedValue -= getVirtualAddress(SymB, SymBSec);
}

void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
Expand Down
83 changes: 83 additions & 0 deletions llvm/test/CodeGen/PowerPC/aix-xcoff-reloc-symb.mir
@@ -0,0 +1,83 @@
# RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc-ibm-aix-xcoff -x mir -verify-machineinstrs -start-after=lazy-machine-block-freq -filetype=obj -o %t.o < %s
# RUN: llvm-readobj --relocs --expand-relocs -t %t.o | FileCheck --check-prefixes=RELOC,SYM %s
# RUN: llvm-objdump -D %t.o | FileCheck --check-prefix=DIS %s

---
name: foo
alignment: 16
tracksRegLiveness: true
jumpTable:
kind: label-difference32
entries:
- id: 0
blocks: [ '%bb.0' ]
body: |
bb.0:
successors: %bb.0(0x20000000)
liveins: $r2
renamable $r3 = LWZtoc %jump-table.0, $r2 :: (load 4 from got)
BLR implicit $lr, implicit $rm, implicit killed $r3
...

# RELOC: Relocation {{[{][[:space:]] *}}Virtual Address: 0x8
# RELOC-NEXT: Symbol: .text ([[#TXT_INDX:]])
# RELOC-NEXT: IsSigned: No
# RELOC-NEXT: FixupBitValue: 0
# RELOC-NEXT: Length: 32
# RELOC-NEXT: Type: R_POS (0x0)
# RELOC-NEXT: }
# RELOC-NEXT: Relocation {
# RELOC-NEXT: Virtual Address: 0x8
# RELOC-NEXT: Symbol: .rodata ([[#RO_INDX:]])
# RELOC-NEXT: IsSigned: No
# RELOC-NEXT: FixupBitValue: 0
# RELOC-NEXT: Length: 32
# RELOC-NEXT: Type: R_NEG (0x1)
# RELOC-NEXT: }

# SYM: Symbol {{[{][[:space:]] *}}Index: [[#TXT_INDX]]{{[[:space:]] *}}Name: .text
# SYM-NEXT: Value (RelocatableAddress): 0x0
# SYM-NEXT: Section: .text
# SYM-NEXT: Type: 0x0
# SYM-NEXT: StorageClass: C_HIDEXT (0x6B)
# SYM-NEXT: NumberOfAuxEntries: 1
# SYM-NEXT: CSECT Auxiliary Entry {
# SYM-NEXT: Index: [[#TXT_INDX+1]]
# SYM-NEXT: SectionLen: 8
# SYM-NEXT: ParameterHashIndex: 0x0
# SYM-NEXT: TypeChkSectNum: 0x0
# SYM-NEXT: SymbolAlignmentLog2: 4
# SYM-NEXT: SymbolType: XTY_SD (0x1)
# SYM-NEXT: StorageMappingClass: XMC_PR (0x0)
# SYM-NEXT: StabInfoIndex: 0x0
# SYM-NEXT: StabSectNum: 0x0
# SYM-NEXT: }
# SYM-NEXT: }
# SYM: Symbol {{[{][[:space:]] *}}Index: [[#RO_INDX]]{{[[:space:]] *}}Name: .rodata
# SYM-NEXT: Value (RelocatableAddress): 0x8
# SYM-NEXT: Section: .text
# SYM-NEXT: Type: 0x0
# SYM-NEXT: StorageClass: C_HIDEXT (0x6B)
# SYM-NEXT: NumberOfAuxEntries: 1
# SYM-NEXT: CSECT Auxiliary Entry {
# SYM-NEXT: Index: [[#RO_INDX+1]]
# SYM-NEXT: SectionLen: 4
# SYM-NEXT: ParameterHashIndex: 0x0
# SYM-NEXT: TypeChkSectNum: 0x0
# SYM-NEXT: SymbolAlignmentLog2: 2
# SYM-NEXT: SymbolType: XTY_SD (0x1)
# SYM-NEXT: StorageMappingClass: XMC_RO (0x1)
# SYM-NEXT: StabInfoIndex: 0x0
# SYM-NEXT: StabSectNum: 0x0
# SYM-NEXT: }
# SYM-NEXT: }

# DIS: Disassembly of section .text:
# DIS-EMPTY:
# DIS-NEXT: 00000000 <.text>:
# DIS-NEXT: 0: 80 62 00 00 lwz 3, 0(2)
# DIS-NEXT: 4: 4e 80 00 20 blr
# DIS-EMPTY:
# DIS-NEXT: 00000008 <.rodata>:
# DIS-NEXT: 8: ff ff ff f8 fmsub 31, 31, 31, 31
# DIS-EMPTY:

0 comments on commit c3c67e9

Please sign in to comment.