1*0b57cec5SDimitry Andric //===-- RuntimeDyldELFMips.cpp ---- ELF/Mips specific code. -----*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric
9*0b57cec5SDimitry Andric #include "RuntimeDyldELFMips.h"
10*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
11*0b57cec5SDimitry Andric
12*0b57cec5SDimitry Andric #define DEBUG_TYPE "dyld"
13*0b57cec5SDimitry Andric
resolveRelocation(const RelocationEntry & RE,uint64_t Value)14*0b57cec5SDimitry Andric void RuntimeDyldELFMips::resolveRelocation(const RelocationEntry &RE,
15*0b57cec5SDimitry Andric uint64_t Value) {
16*0b57cec5SDimitry Andric const SectionEntry &Section = Sections[RE.SectionID];
17*0b57cec5SDimitry Andric if (IsMipsO32ABI)
18*0b57cec5SDimitry Andric resolveMIPSO32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend);
19*0b57cec5SDimitry Andric else if (IsMipsN32ABI) {
20*0b57cec5SDimitry Andric resolveMIPSN32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
21*0b57cec5SDimitry Andric RE.SymOffset, RE.SectionID);
22*0b57cec5SDimitry Andric } else if (IsMipsN64ABI)
23*0b57cec5SDimitry Andric resolveMIPSN64Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
24*0b57cec5SDimitry Andric RE.SymOffset, RE.SectionID);
25*0b57cec5SDimitry Andric else
26*0b57cec5SDimitry Andric llvm_unreachable("Mips ABI not handled");
27*0b57cec5SDimitry Andric }
28*0b57cec5SDimitry Andric
evaluateRelocation(const RelocationEntry & RE,uint64_t Value,uint64_t Addend)29*0b57cec5SDimitry Andric uint64_t RuntimeDyldELFMips::evaluateRelocation(const RelocationEntry &RE,
30*0b57cec5SDimitry Andric uint64_t Value,
31*0b57cec5SDimitry Andric uint64_t Addend) {
32*0b57cec5SDimitry Andric if (IsMipsN32ABI) {
33*0b57cec5SDimitry Andric const SectionEntry &Section = Sections[RE.SectionID];
34*0b57cec5SDimitry Andric Value = evaluateMIPS64Relocation(Section, RE.Offset, Value, RE.RelType,
35*0b57cec5SDimitry Andric Addend, RE.SymOffset, RE.SectionID);
36*0b57cec5SDimitry Andric return Value;
37*0b57cec5SDimitry Andric }
38*0b57cec5SDimitry Andric llvm_unreachable("Not reachable");
39*0b57cec5SDimitry Andric }
40*0b57cec5SDimitry Andric
applyRelocation(const RelocationEntry & RE,uint64_t Value)41*0b57cec5SDimitry Andric void RuntimeDyldELFMips::applyRelocation(const RelocationEntry &RE,
42*0b57cec5SDimitry Andric uint64_t Value) {
43*0b57cec5SDimitry Andric if (IsMipsN32ABI) {
44*0b57cec5SDimitry Andric const SectionEntry &Section = Sections[RE.SectionID];
45*0b57cec5SDimitry Andric applyMIPSRelocation(Section.getAddressWithOffset(RE.Offset), Value,
46*0b57cec5SDimitry Andric RE.RelType);
47*0b57cec5SDimitry Andric return;
48*0b57cec5SDimitry Andric }
49*0b57cec5SDimitry Andric llvm_unreachable("Not reachable");
50*0b57cec5SDimitry Andric }
51*0b57cec5SDimitry Andric
52*0b57cec5SDimitry Andric int64_t
evaluateMIPS32Relocation(const SectionEntry & Section,uint64_t Offset,uint64_t Value,uint32_t Type)53*0b57cec5SDimitry Andric RuntimeDyldELFMips::evaluateMIPS32Relocation(const SectionEntry &Section,
54*0b57cec5SDimitry Andric uint64_t Offset, uint64_t Value,
55*0b57cec5SDimitry Andric uint32_t Type) {
56*0b57cec5SDimitry Andric
57*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x"
58*0b57cec5SDimitry Andric << format("%llx", Section.getAddressWithOffset(Offset))
59*0b57cec5SDimitry Andric << " FinalAddress: 0x"
60*0b57cec5SDimitry Andric << format("%llx", Section.getLoadAddressWithOffset(Offset))
61*0b57cec5SDimitry Andric << " Value: 0x" << format("%llx", Value) << " Type: 0x"
62*0b57cec5SDimitry Andric << format("%x", Type) << "\n");
63*0b57cec5SDimitry Andric
64*0b57cec5SDimitry Andric switch (Type) {
65*0b57cec5SDimitry Andric default:
66*0b57cec5SDimitry Andric llvm_unreachable("Unknown relocation type!");
67*0b57cec5SDimitry Andric return Value;
68*0b57cec5SDimitry Andric case ELF::R_MIPS_32:
69*0b57cec5SDimitry Andric return Value;
70*0b57cec5SDimitry Andric case ELF::R_MIPS_26:
71*0b57cec5SDimitry Andric return Value >> 2;
72*0b57cec5SDimitry Andric case ELF::R_MIPS_HI16:
73*0b57cec5SDimitry Andric // Get the higher 16-bits. Also add 1 if bit 15 is 1.
74*0b57cec5SDimitry Andric return (Value + 0x8000) >> 16;
75*0b57cec5SDimitry Andric case ELF::R_MIPS_LO16:
76*0b57cec5SDimitry Andric return Value;
77*0b57cec5SDimitry Andric case ELF::R_MIPS_PC32: {
78*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
79*0b57cec5SDimitry Andric return Value - FinalAddress;
80*0b57cec5SDimitry Andric }
81*0b57cec5SDimitry Andric case ELF::R_MIPS_PC16: {
82*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
83*0b57cec5SDimitry Andric return (Value - FinalAddress) >> 2;
84*0b57cec5SDimitry Andric }
85*0b57cec5SDimitry Andric case ELF::R_MIPS_PC19_S2: {
86*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
87*0b57cec5SDimitry Andric return (Value - (FinalAddress & ~0x3)) >> 2;
88*0b57cec5SDimitry Andric }
89*0b57cec5SDimitry Andric case ELF::R_MIPS_PC21_S2: {
90*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
91*0b57cec5SDimitry Andric return (Value - FinalAddress) >> 2;
92*0b57cec5SDimitry Andric }
93*0b57cec5SDimitry Andric case ELF::R_MIPS_PC26_S2: {
94*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
95*0b57cec5SDimitry Andric return (Value - FinalAddress) >> 2;
96*0b57cec5SDimitry Andric }
97*0b57cec5SDimitry Andric case ELF::R_MIPS_PCHI16: {
98*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
99*0b57cec5SDimitry Andric return (Value - FinalAddress + 0x8000) >> 16;
100*0b57cec5SDimitry Andric }
101*0b57cec5SDimitry Andric case ELF::R_MIPS_PCLO16: {
102*0b57cec5SDimitry Andric uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
103*0b57cec5SDimitry Andric return Value - FinalAddress;
104*0b57cec5SDimitry Andric }
105*0b57cec5SDimitry Andric }
106*0b57cec5SDimitry Andric }
107*0b57cec5SDimitry Andric
evaluateMIPS64Relocation(const SectionEntry & Section,uint64_t Offset,uint64_t Value,uint32_t Type,int64_t Addend,uint64_t SymOffset,SID SectionID)108*0b57cec5SDimitry Andric int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation(
109*0b57cec5SDimitry Andric const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type,
110*0b57cec5SDimitry Andric int64_t Addend, uint64_t SymOffset, SID SectionID) {
111*0b57cec5SDimitry Andric
112*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x"
113*0b57cec5SDimitry Andric << format("%llx", Section.getAddressWithOffset(Offset))
114*0b57cec5SDimitry Andric << " FinalAddress: 0x"
115*0b57cec5SDimitry Andric << format("%llx", Section.getLoadAddressWithOffset(Offset))
116*0b57cec5SDimitry Andric << " Value: 0x" << format("%llx", Value) << " Type: 0x"
117*0b57cec5SDimitry Andric << format("%x", Type) << " Addend: 0x"
118*0b57cec5SDimitry Andric << format("%llx", Addend)
119*0b57cec5SDimitry Andric << " Offset: " << format("%llx" PRIx64, Offset)
120*0b57cec5SDimitry Andric << " SID: " << format("%d", SectionID)
121*0b57cec5SDimitry Andric << " SymOffset: " << format("%x", SymOffset) << "\n");
122*0b57cec5SDimitry Andric
123*0b57cec5SDimitry Andric switch (Type) {
124*0b57cec5SDimitry Andric default:
125*0b57cec5SDimitry Andric llvm_unreachable("Not implemented relocation type!");
126*0b57cec5SDimitry Andric break;
127*0b57cec5SDimitry Andric case ELF::R_MIPS_JALR:
128*0b57cec5SDimitry Andric case ELF::R_MIPS_NONE:
129*0b57cec5SDimitry Andric break;
130*0b57cec5SDimitry Andric case ELF::R_MIPS_32:
131*0b57cec5SDimitry Andric case ELF::R_MIPS_64:
132*0b57cec5SDimitry Andric return Value + Addend;
133*0b57cec5SDimitry Andric case ELF::R_MIPS_26:
134*0b57cec5SDimitry Andric return ((Value + Addend) >> 2) & 0x3ffffff;
135*0b57cec5SDimitry Andric case ELF::R_MIPS_GPREL16: {
136*0b57cec5SDimitry Andric uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]);
137*0b57cec5SDimitry Andric return Value + Addend - (GOTAddr + 0x7ff0);
138*0b57cec5SDimitry Andric }
139*0b57cec5SDimitry Andric case ELF::R_MIPS_SUB:
140*0b57cec5SDimitry Andric return Value - Addend;
141*0b57cec5SDimitry Andric case ELF::R_MIPS_HI16:
142*0b57cec5SDimitry Andric // Get the higher 16-bits. Also add 1 if bit 15 is 1.
143*0b57cec5SDimitry Andric return ((Value + Addend + 0x8000) >> 16) & 0xffff;
144*0b57cec5SDimitry Andric case ELF::R_MIPS_LO16:
145*0b57cec5SDimitry Andric return (Value + Addend) & 0xffff;
146*0b57cec5SDimitry Andric case ELF::R_MIPS_HIGHER:
147*0b57cec5SDimitry Andric return ((Value + Addend + 0x80008000) >> 32) & 0xffff;
148*0b57cec5SDimitry Andric case ELF::R_MIPS_HIGHEST:
149*0b57cec5SDimitry Andric return ((Value + Addend + 0x800080008000) >> 48) & 0xffff;
150*0b57cec5SDimitry Andric case ELF::R_MIPS_CALL16:
151*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_DISP:
152*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_PAGE: {
153*0b57cec5SDimitry Andric uint8_t *LocalGOTAddr =
154*0b57cec5SDimitry Andric getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset;
155*0b57cec5SDimitry Andric uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, getGOTEntrySize());
156*0b57cec5SDimitry Andric
157*0b57cec5SDimitry Andric Value += Addend;
158*0b57cec5SDimitry Andric if (Type == ELF::R_MIPS_GOT_PAGE)
159*0b57cec5SDimitry Andric Value = (Value + 0x8000) & ~0xffff;
160*0b57cec5SDimitry Andric
161*0b57cec5SDimitry Andric if (GOTEntry)
162*0b57cec5SDimitry Andric assert(GOTEntry == Value &&
163*0b57cec5SDimitry Andric "GOT entry has two different addresses.");
164*0b57cec5SDimitry Andric else
165*0b57cec5SDimitry Andric writeBytesUnaligned(Value, LocalGOTAddr, getGOTEntrySize());
166*0b57cec5SDimitry Andric
167*0b57cec5SDimitry Andric return (SymOffset - 0x7ff0) & 0xffff;
168*0b57cec5SDimitry Andric }
169*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_OFST: {
170*0b57cec5SDimitry Andric int64_t page = (Value + Addend + 0x8000) & ~0xffff;
171*0b57cec5SDimitry Andric return (Value + Addend - page) & 0xffff;
172*0b57cec5SDimitry Andric }
173*0b57cec5SDimitry Andric case ELF::R_MIPS_GPREL32: {
174*0b57cec5SDimitry Andric uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]);
175*0b57cec5SDimitry Andric return Value + Addend - (GOTAddr + 0x7ff0);
176*0b57cec5SDimitry Andric }
177*0b57cec5SDimitry Andric case ELF::R_MIPS_PC16: {
178*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
179*0b57cec5SDimitry Andric return ((Value + Addend - FinalAddress) >> 2) & 0xffff;
180*0b57cec5SDimitry Andric }
181*0b57cec5SDimitry Andric case ELF::R_MIPS_PC32: {
182*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
183*0b57cec5SDimitry Andric return Value + Addend - FinalAddress;
184*0b57cec5SDimitry Andric }
185*0b57cec5SDimitry Andric case ELF::R_MIPS_PC18_S3: {
186*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
187*0b57cec5SDimitry Andric return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
188*0b57cec5SDimitry Andric }
189*0b57cec5SDimitry Andric case ELF::R_MIPS_PC19_S2: {
190*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
191*0b57cec5SDimitry Andric return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
192*0b57cec5SDimitry Andric }
193*0b57cec5SDimitry Andric case ELF::R_MIPS_PC21_S2: {
194*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
195*0b57cec5SDimitry Andric return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;
196*0b57cec5SDimitry Andric }
197*0b57cec5SDimitry Andric case ELF::R_MIPS_PC26_S2: {
198*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
199*0b57cec5SDimitry Andric return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
200*0b57cec5SDimitry Andric }
201*0b57cec5SDimitry Andric case ELF::R_MIPS_PCHI16: {
202*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
203*0b57cec5SDimitry Andric return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
204*0b57cec5SDimitry Andric }
205*0b57cec5SDimitry Andric case ELF::R_MIPS_PCLO16: {
206*0b57cec5SDimitry Andric uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
207*0b57cec5SDimitry Andric return (Value + Addend - FinalAddress) & 0xffff;
208*0b57cec5SDimitry Andric }
209*0b57cec5SDimitry Andric }
210*0b57cec5SDimitry Andric return 0;
211*0b57cec5SDimitry Andric }
212*0b57cec5SDimitry Andric
applyMIPSRelocation(uint8_t * TargetPtr,int64_t Value,uint32_t Type)213*0b57cec5SDimitry Andric void RuntimeDyldELFMips::applyMIPSRelocation(uint8_t *TargetPtr, int64_t Value,
214*0b57cec5SDimitry Andric uint32_t Type) {
215*0b57cec5SDimitry Andric uint32_t Insn = readBytesUnaligned(TargetPtr, 4);
216*0b57cec5SDimitry Andric
217*0b57cec5SDimitry Andric switch (Type) {
218*0b57cec5SDimitry Andric default:
219*0b57cec5SDimitry Andric llvm_unreachable("Unknown relocation type!");
220*0b57cec5SDimitry Andric break;
221*0b57cec5SDimitry Andric case ELF::R_MIPS_GPREL16:
222*0b57cec5SDimitry Andric case ELF::R_MIPS_HI16:
223*0b57cec5SDimitry Andric case ELF::R_MIPS_LO16:
224*0b57cec5SDimitry Andric case ELF::R_MIPS_HIGHER:
225*0b57cec5SDimitry Andric case ELF::R_MIPS_HIGHEST:
226*0b57cec5SDimitry Andric case ELF::R_MIPS_PC16:
227*0b57cec5SDimitry Andric case ELF::R_MIPS_PCHI16:
228*0b57cec5SDimitry Andric case ELF::R_MIPS_PCLO16:
229*0b57cec5SDimitry Andric case ELF::R_MIPS_CALL16:
230*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_DISP:
231*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_PAGE:
232*0b57cec5SDimitry Andric case ELF::R_MIPS_GOT_OFST:
233*0b57cec5SDimitry Andric Insn = (Insn & 0xffff0000) | (Value & 0x0000ffff);
234*0b57cec5SDimitry Andric writeBytesUnaligned(Insn, TargetPtr, 4);
235*0b57cec5SDimitry Andric break;
236*0b57cec5SDimitry Andric case ELF::R_MIPS_PC18_S3:
237*0b57cec5SDimitry Andric Insn = (Insn & 0xfffc0000) | (Value & 0x0003ffff);
238*0b57cec5SDimitry Andric writeBytesUnaligned(Insn, TargetPtr, 4);
239*0b57cec5SDimitry Andric break;
240*0b57cec5SDimitry Andric case ELF::R_MIPS_PC19_S2:
241*0b57cec5SDimitry Andric Insn = (Insn & 0xfff80000) | (Value & 0x0007ffff);
242*0b57cec5SDimitry Andric writeBytesUnaligned(Insn, TargetPtr, 4);
243*0b57cec5SDimitry Andric break;
244*0b57cec5SDimitry Andric case ELF::R_MIPS_PC21_S2:
245*0b57cec5SDimitry Andric Insn = (Insn & 0xffe00000) | (Value & 0x001fffff);
246*0b57cec5SDimitry Andric writeBytesUnaligned(Insn, TargetPtr, 4);
247*0b57cec5SDimitry Andric break;
248*0b57cec5SDimitry Andric case ELF::R_MIPS_26:
249*0b57cec5SDimitry Andric case ELF::R_MIPS_PC26_S2:
250*0b57cec5SDimitry Andric Insn = (Insn & 0xfc000000) | (Value & 0x03ffffff);
251*0b57cec5SDimitry Andric writeBytesUnaligned(Insn, TargetPtr, 4);
252*0b57cec5SDimitry Andric break;
253*0b57cec5SDimitry Andric case ELF::R_MIPS_32:
254*0b57cec5SDimitry Andric case ELF::R_MIPS_GPREL32:
255*0b57cec5SDimitry Andric case ELF::R_MIPS_PC32:
256*0b57cec5SDimitry Andric writeBytesUnaligned(Value & 0xffffffff, TargetPtr, 4);
257*0b57cec5SDimitry Andric break;
258*0b57cec5SDimitry Andric case ELF::R_MIPS_64:
259*0b57cec5SDimitry Andric case ELF::R_MIPS_SUB:
260*0b57cec5SDimitry Andric writeBytesUnaligned(Value, TargetPtr, 8);
261*0b57cec5SDimitry Andric break;
262*0b57cec5SDimitry Andric }
263*0b57cec5SDimitry Andric }
264*0b57cec5SDimitry Andric
resolveMIPSN32Relocation(const SectionEntry & Section,uint64_t Offset,uint64_t Value,uint32_t Type,int64_t Addend,uint64_t SymOffset,SID SectionID)265*0b57cec5SDimitry Andric void RuntimeDyldELFMips::resolveMIPSN32Relocation(
266*0b57cec5SDimitry Andric const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type,
267*0b57cec5SDimitry Andric int64_t Addend, uint64_t SymOffset, SID SectionID) {
268*0b57cec5SDimitry Andric int64_t CalculatedValue = evaluateMIPS64Relocation(
269*0b57cec5SDimitry Andric Section, Offset, Value, Type, Addend, SymOffset, SectionID);
270*0b57cec5SDimitry Andric applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue,
271*0b57cec5SDimitry Andric Type);
272*0b57cec5SDimitry Andric }
273*0b57cec5SDimitry Andric
resolveMIPSN64Relocation(const SectionEntry & Section,uint64_t Offset,uint64_t Value,uint32_t Type,int64_t Addend,uint64_t SymOffset,SID SectionID)274*0b57cec5SDimitry Andric void RuntimeDyldELFMips::resolveMIPSN64Relocation(
275*0b57cec5SDimitry Andric const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type,
276*0b57cec5SDimitry Andric int64_t Addend, uint64_t SymOffset, SID SectionID) {
277*0b57cec5SDimitry Andric uint32_t r_type = Type & 0xff;
278*0b57cec5SDimitry Andric uint32_t r_type2 = (Type >> 8) & 0xff;
279*0b57cec5SDimitry Andric uint32_t r_type3 = (Type >> 16) & 0xff;
280*0b57cec5SDimitry Andric
281*0b57cec5SDimitry Andric // RelType is used to keep information for which relocation type we are
282*0b57cec5SDimitry Andric // applying relocation.
283*0b57cec5SDimitry Andric uint32_t RelType = r_type;
284*0b57cec5SDimitry Andric int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,
285*0b57cec5SDimitry Andric RelType, Addend,
286*0b57cec5SDimitry Andric SymOffset, SectionID);
287*0b57cec5SDimitry Andric if (r_type2 != ELF::R_MIPS_NONE) {
288*0b57cec5SDimitry Andric RelType = r_type2;
289*0b57cec5SDimitry Andric CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
290*0b57cec5SDimitry Andric CalculatedValue, SymOffset,
291*0b57cec5SDimitry Andric SectionID);
292*0b57cec5SDimitry Andric }
293*0b57cec5SDimitry Andric if (r_type3 != ELF::R_MIPS_NONE) {
294*0b57cec5SDimitry Andric RelType = r_type3;
295*0b57cec5SDimitry Andric CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
296*0b57cec5SDimitry Andric CalculatedValue, SymOffset,
297*0b57cec5SDimitry Andric SectionID);
298*0b57cec5SDimitry Andric }
299*0b57cec5SDimitry Andric applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue,
300*0b57cec5SDimitry Andric RelType);
301*0b57cec5SDimitry Andric }
302*0b57cec5SDimitry Andric
resolveMIPSO32Relocation(const SectionEntry & Section,uint64_t Offset,uint32_t Value,uint32_t Type,int32_t Addend)303*0b57cec5SDimitry Andric void RuntimeDyldELFMips::resolveMIPSO32Relocation(const SectionEntry &Section,
304*0b57cec5SDimitry Andric uint64_t Offset,
305*0b57cec5SDimitry Andric uint32_t Value, uint32_t Type,
306*0b57cec5SDimitry Andric int32_t Addend) {
307*0b57cec5SDimitry Andric uint8_t *TargetPtr = Section.getAddressWithOffset(Offset);
308*0b57cec5SDimitry Andric Value += Addend;
309*0b57cec5SDimitry Andric
310*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "resolveMIPSO32Relocation, LocalAddress: "
311*0b57cec5SDimitry Andric << Section.getAddressWithOffset(Offset) << " FinalAddress: "
312*0b57cec5SDimitry Andric << format("%p", Section.getLoadAddressWithOffset(Offset))
313*0b57cec5SDimitry Andric << " Value: " << format("%x", Value) << " Type: "
314*0b57cec5SDimitry Andric << format("%x", Type) << " Addend: " << format("%x", Addend)
315*0b57cec5SDimitry Andric << " SymOffset: " << format("%x", Offset) << "\n");
316*0b57cec5SDimitry Andric
317*0b57cec5SDimitry Andric Value = evaluateMIPS32Relocation(Section, Offset, Value, Type);
318*0b57cec5SDimitry Andric
319*0b57cec5SDimitry Andric applyMIPSRelocation(TargetPtr, Value, Type);
320*0b57cec5SDimitry Andric }
321