33
33
virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
34
34
const MCFixup &Fixup,
35
35
bool IsPCRel) const;
36
virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset);
38
virtual void sortRelocs(const MCAssembler &Asm,
39
std::vector<ELFRelocationEntry> &Relocs);
42
class PPCELFRelocationEntry : public ELFRelocationEntry {
44
PPCELFRelocationEntry(const ELFRelocationEntry &RE);
45
bool operator<(const PPCELFRelocationEntry &RE) const {
46
return (RE.r_offset < r_offset ||
47
(RE.r_offset == r_offset && RE.Type > Type));
52
PPCELFRelocationEntry::PPCELFRelocationEntry(const ELFRelocationEntry &RE)
53
: ELFRelocationEntry(RE.r_offset, RE.Index, RE.Type, RE.Symbol,
54
RE.r_addend, *RE.Fixup) {}
56
39
PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
57
40
: MCELFObjectTargetWriter(Is64Bit, OSABI,
58
41
Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
95
81
case PPC::fixup_ppc_brcond14:
96
82
Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
98
case PPC::fixup_ppc_ha16:
84
case PPC::fixup_ppc_half16:
99
85
switch (Modifier) {
100
86
default: llvm_unreachable("Unsupported Modifier");
101
87
case MCSymbolRefExpr::VK_PPC_TPREL16_HA:
104
90
case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
105
91
Type = ELF::R_PPC64_DTPREL16_HA;
107
case MCSymbolRefExpr::VK_None:
93
case MCSymbolRefExpr::VK_PPC_ADDR16_HA:
108
94
Type = ELF::R_PPC_ADDR16_HA;
110
96
case MCSymbolRefExpr::VK_PPC_TOC16_HA:
119
105
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA:
120
106
Type = ELF::R_PPC64_GOT_TLSLD16_HA;
124
case PPC::fixup_ppc_lo16:
126
default: llvm_unreachable("Unsupported Modifier");
127
108
case MCSymbolRefExpr::VK_PPC_TPREL16_LO:
128
109
Type = ELF::R_PPC_TPREL16_LO;
131
112
Type = ELF::R_PPC64_DTPREL16_LO;
133
114
case MCSymbolRefExpr::VK_None:
115
Type = ELF::R_PPC_ADDR16;
117
case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
134
118
Type = ELF::R_PPC_ADDR16_LO;
136
120
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
150
case PPC::fixup_ppc_lo16_ds:
134
case PPC::fixup_ppc_half16ds:
151
135
switch (Modifier) {
152
136
default: llvm_unreachable("Unsupported Modifier");
153
137
case MCSymbolRefExpr::VK_None:
154
138
Type = ELF::R_PPC64_ADDR16_DS;
140
case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
141
Type = ELF::R_PPC64_ADDR16_LO_DS;
156
143
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
157
144
Type = ELF::R_PPC64_TOC16_DS;
231
void PPCELFObjectWriter::
232
adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) {
233
switch ((unsigned)Fixup.getKind()) {
234
case PPC::fixup_ppc_ha16:
235
case PPC::fixup_ppc_lo16:
236
case PPC::fixup_ppc_lo16_ds:
244
// The standard sorter only sorts on the r_offset field, but PowerPC can
245
// have multiple relocations at the same offset. Sort secondarily on the
246
// relocation type to avoid nondeterminism.
247
void PPCELFObjectWriter::sortRelocs(const MCAssembler &Asm,
248
std::vector<ELFRelocationEntry> &Relocs) {
250
// Copy to a temporary vector of relocation entries having a different
252
std::vector<PPCELFRelocationEntry> TmpRelocs;
254
for (std::vector<ELFRelocationEntry>::iterator R = Relocs.begin();
255
R != Relocs.end(); ++R) {
256
TmpRelocs.push_back(PPCELFRelocationEntry(*R));
259
// Sort in place by ascending r_offset and descending r_type.
260
array_pod_sort(TmpRelocs.begin(), TmpRelocs.end());
262
// Copy back to the original vector.
264
for (std::vector<PPCELFRelocationEntry>::iterator R = TmpRelocs.begin();
265
R != TmpRelocs.end(); ++R, ++I) {
266
Relocs[I] = ELFRelocationEntry(R->r_offset, R->Index, R->Type,
267
R->Symbol, R->r_addend, *R->Fixup);
272
218
MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,