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