forked from OSchip/llvm-project
[XCOFF][AIX] Relocation support for SymB
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
This commit is contained in:
parent
4578fa8a1c
commit
c3c67e9531
|
@ -384,11 +384,26 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||||
const MCFragment *Fragment,
|
const MCFragment *Fragment,
|
||||||
const MCFixup &Fixup, MCValue Target,
|
const MCFixup &Fixup, MCValue Target,
|
||||||
uint64_t &FixedValue) {
|
uint64_t &FixedValue) {
|
||||||
|
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()];
|
||||||
|
};
|
||||||
|
|
||||||
if (Target.getSymB())
|
auto getVirtualAddress = [this,
|
||||||
report_fatal_error("Handling Target.SymB for relocation is unimplemented.");
|
&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 &SymA = Target.getSymA()->getSymbol();
|
const MCSymbol *const SymA = &Target.getSymA()->getSymbol();
|
||||||
|
|
||||||
MCAsmBackend &Backend = Asm.getBackend();
|
MCAsmBackend &Backend = Asm.getBackend();
|
||||||
bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
|
bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
|
||||||
|
@ -399,26 +414,15 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||||
std::tie(Type, SignAndSize) =
|
std::tie(Type, SignAndSize) =
|
||||||
TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
|
TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
|
||||||
|
|
||||||
const MCSectionXCOFF *SymASec =
|
const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
|
||||||
getContainingCsect(cast<MCSymbolXCOFF>(&SymA));
|
|
||||||
assert(SectionMap.find(SymASec) != SectionMap.end() &&
|
assert(SectionMap.find(SymASec) != SectionMap.end() &&
|
||||||
"Expected containing csect to exist in map.");
|
"Expected containing csect to exist in map.");
|
||||||
|
|
||||||
// If we could not find SymA directly in SymbolIndexMap, this symbol could
|
const uint32_t Index = getIndex(SymA, SymASec);
|
||||||
// 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()];
|
|
||||||
|
|
||||||
if (Type == XCOFF::RelocationType::R_POS)
|
if (Type == XCOFF::RelocationType::R_POS)
|
||||||
// The FixedValue should be symbol's virtual address in this object file
|
// The FixedValue should be symbol's virtual address in this object file
|
||||||
// plus any constant value that we might get.
|
// plus any constant value that we might get.
|
||||||
// Notice that SymA.isDefined() could return false, but SymASec could still
|
FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
|
||||||
// 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();
|
|
||||||
else if (Type == XCOFF::RelocationType::R_TOC)
|
else if (Type == XCOFF::RelocationType::R_TOC)
|
||||||
// The FixedValue should be the TC entry offset from TOC-base.
|
// The FixedValue should be the TC entry offset from TOC-base.
|
||||||
FixedValue = SectionMap[SymASec]->Address - TOCCsects.front().Address;
|
FixedValue = SectionMap[SymASec]->Address - TOCCsects.front().Address;
|
||||||
|
@ -435,6 +439,33 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
|
||||||
assert(SectionMap.find(RelocationSec) != SectionMap.end() &&
|
assert(SectionMap.find(RelocationSec) != SectionMap.end() &&
|
||||||
"Expected containing csect to exist in map.");
|
"Expected containing csect to exist in map.");
|
||||||
SectionMap[RelocationSec]->Relocations.push_back(Reloc);
|
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,
|
void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
|
||||||
|
|
|
@ -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:
|
Loading…
Reference in New Issue