13 #define DEBUG_TYPE "dyld"
30 uint64_t RuntimeDyldELFMips::evaluateRelocation(
const RelocationEntry &RE,
35 Value = evaluateMIPS64Relocation(Section, RE.
Offset, Value, RE.
RelType,
55 uint64_t
Offset, uint64_t Value,
58 DEBUG(
dbgs() <<
"evaluateMIPS32Relocation, LocalAddress: 0x"
60 <<
" FinalAddress: 0x"
62 <<
" Value: 0x" <<
format(
"%llx", Value) <<
" Type: 0x"
63 <<
format(
"%x", Type) <<
"\n");
73 case ELF::R_MIPS_HI16:
75 return (Value + 0x8000) >> 16;
76 case ELF::R_MIPS_LO16:
78 case ELF::R_MIPS_PC32: {
80 return Value - FinalAddress;
82 case ELF::R_MIPS_PC16: {
84 return (Value - FinalAddress) >> 2;
86 case ELF::R_MIPS_PC19_S2: {
88 return (Value - (FinalAddress & ~0x3)) >> 2;
90 case ELF::R_MIPS_PC21_S2: {
92 return (Value - FinalAddress) >> 2;
94 case ELF::R_MIPS_PC26_S2: {
96 return (Value - FinalAddress) >> 2;
98 case ELF::R_MIPS_PCHI16: {
100 return (Value - FinalAddress + 0x8000) >> 16;
102 case ELF::R_MIPS_PCLO16: {
104 return Value - FinalAddress;
109 int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation(
111 int64_t Addend, uint64_t SymOffset, SID SectionID) {
113 DEBUG(
dbgs() <<
"evaluateMIPS64Relocation, LocalAddress: 0x"
115 <<
" FinalAddress: 0x"
117 <<
" Value: 0x" <<
format(
"%llx", Value) <<
" Type: 0x"
118 <<
format(
"%x", Type) <<
" Addend: 0x" <<
format(
"%llx", Addend)
119 <<
" SymOffset: " <<
format(
"%x", SymOffset) <<
"\n");
125 case ELF::R_MIPS_JALR:
126 case ELF::R_MIPS_NONE:
130 return Value + Addend;
132 return ((Value + Addend) >> 2) & 0x3ffffff;
133 case ELF::R_MIPS_GPREL16: {
135 return Value + Addend - (GOTAddr + 0x7ff0);
137 case ELF::R_MIPS_SUB:
138 return Value - Addend;
139 case ELF::R_MIPS_HI16:
141 return ((Value + Addend + 0x8000) >> 16) & 0xffff;
142 case ELF::R_MIPS_LO16:
143 return (Value + Addend) & 0xffff;
144 case ELF::R_MIPS_CALL16:
145 case ELF::R_MIPS_GOT_DISP:
146 case ELF::R_MIPS_GOT_PAGE: {
147 uint8_t *LocalGOTAddr =
152 if (Type == ELF::R_MIPS_GOT_PAGE)
153 Value = (Value + 0x8000) & ~0xffff;
156 assert(GOTEntry == Value &&
157 "GOT entry has two different addresses.");
161 return (SymOffset - 0x7ff0) & 0xffff;
163 case ELF::R_MIPS_GOT_OFST: {
164 int64_t page = (Value + Addend + 0x8000) & ~0xffff;
165 return (Value + Addend - page) & 0xffff;
167 case ELF::R_MIPS_GPREL32: {
169 return Value + Addend - (GOTAddr + 0x7ff0);
171 case ELF::R_MIPS_PC16: {
173 return ((Value + Addend - FinalAddress) >> 2) & 0xffff;
175 case ELF::R_MIPS_PC32: {
177 return Value + Addend - FinalAddress;
179 case ELF::R_MIPS_PC18_S3: {
181 return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
183 case ELF::R_MIPS_PC19_S2: {
185 return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
187 case ELF::R_MIPS_PC21_S2: {
189 return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;
191 case ELF::R_MIPS_PC26_S2: {
193 return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
195 case ELF::R_MIPS_PCHI16: {
197 return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
199 case ELF::R_MIPS_PCLO16: {
201 return (Value + Addend - FinalAddress) & 0xffff;
207 void RuntimeDyldELFMips::applyMIPSRelocation(uint8_t *TargetPtr, int64_t Value,
215 case ELF::R_MIPS_GPREL16:
216 case ELF::R_MIPS_HI16:
217 case ELF::R_MIPS_LO16:
218 case ELF::R_MIPS_PC16:
219 case ELF::R_MIPS_PCHI16:
220 case ELF::R_MIPS_PCLO16:
221 case ELF::R_MIPS_CALL16:
222 case ELF::R_MIPS_GOT_DISP:
223 case ELF::R_MIPS_GOT_PAGE:
224 case ELF::R_MIPS_GOT_OFST:
225 Insn = (Insn & 0xffff0000) | (Value & 0x0000ffff);
228 case ELF::R_MIPS_PC18_S3:
229 Insn = (Insn & 0xfffc0000) | (Value & 0x0003ffff);
232 case ELF::R_MIPS_PC19_S2:
233 Insn = (Insn & 0xfff80000) | (Value & 0x0007ffff);
236 case ELF::R_MIPS_PC21_S2:
237 Insn = (Insn & 0xffe00000) | (Value & 0x001fffff);
241 case ELF::R_MIPS_PC26_S2:
242 Insn = (Insn & 0xfc000000) | (Value & 0x03ffffff);
246 case ELF::R_MIPS_GPREL32:
247 case ELF::R_MIPS_PC32:
251 case ELF::R_MIPS_SUB:
259 int64_t Addend, uint64_t SymOffset,
SID SectionID) {
260 int64_t CalculatedValue = evaluateMIPS64Relocation(
261 Section, Offset, Value, Type, Addend, SymOffset, SectionID);
268 int64_t Addend, uint64_t SymOffset,
SID SectionID) {
270 uint32_t r_type2 = (Type >> 8) & 0xff;
271 uint32_t r_type3 = (Type >> 16) & 0xff;
276 int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,
278 SymOffset, SectionID);
279 if (r_type2 != ELF::R_MIPS_NONE) {
281 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
282 CalculatedValue, SymOffset,
285 if (r_type3 != ELF::R_MIPS_NONE) {
287 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
288 CalculatedValue, SymOffset,
302 DEBUG(
dbgs() <<
"resolveMIPSO32Relocation, LocalAddress: "
305 <<
" Value: " <<
format(
"%x", Value)
306 <<
" Type: " <<
format(
"%x", Type)
307 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
309 Value = evaluateMIPS32Relocation(Section, Offset, Value, Type);
311 applyMIPSRelocation(TargetPtr, Value, Type);
RelocationEntry - used to represent relocations internally in the dynamic linker. ...
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
unsigned SectionID
SectionID - the section this relocation points to.
uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const
Return the load address of this section with an offset.
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
uint8_t * getAddressWithOffset(unsigned OffsetBytes) const
Return the address of this section with an offset.
The instances of the Type class are immutable: once they are created, they are never changed...
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
uint8_t * getSectionAddress(unsigned SectionID) const
DenseMap< SID, SID > SectionToGOTMap
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
uint32_t RelType
RelType - relocation type.
void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset, SID SectionID)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t Offset
Offset - offset into the section.
void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset, SID SectionID)
void resolveMIPSO32Relocation(const SectionEntry &Section, uint64_t Offset, uint32_t Value, uint32_t Type, int32_t Addend)
SectionEntry - represents a section emitted into memory by the dynamic linker.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
uint64_t getSectionLoadAddress(unsigned SectionID) const