13 #define DEBUG_TYPE "dyld" 30 uint64_t RuntimeDyldELFMips::evaluateRelocation(
const RelocationEntry &RE,
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) {
115 <<
" FinalAddress: 0x" 117 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x" 118 <<
format(
"%x", Type) <<
" Addend: 0x" 121 <<
" SID: " <<
format(
"%d", SectionID)
122 <<
" SymOffset: " <<
format(
"%x", SymOffset) <<
"\n");
128 case ELF::R_MIPS_JALR:
129 case ELF::R_MIPS_NONE:
133 return Value + Addend;
135 return ((
Value + Addend) >> 2) & 0x3ffffff;
136 case ELF::R_MIPS_GPREL16: {
138 return Value + Addend - (GOTAddr + 0x7ff0);
140 case ELF::R_MIPS_SUB:
141 return Value - Addend;
142 case ELF::R_MIPS_HI16:
144 return ((
Value + Addend + 0x8000) >> 16) & 0xffff;
145 case ELF::R_MIPS_LO16:
146 return (
Value + Addend) & 0xffff;
147 case ELF::R_MIPS_HIGHER:
148 return ((
Value + Addend + 0x80008000) >> 32) & 0xffff;
149 case ELF::R_MIPS_HIGHEST:
150 return ((
Value + Addend + 0x800080008000) >> 48) & 0xffff;
151 case ELF::R_MIPS_CALL16:
152 case ELF::R_MIPS_GOT_DISP:
153 case ELF::R_MIPS_GOT_PAGE: {
154 uint8_t *LocalGOTAddr =
159 if (Type == ELF::R_MIPS_GOT_PAGE)
164 "GOT entry has two different addresses.");
168 return (SymOffset - 0x7ff0) & 0xffff;
170 case ELF::R_MIPS_GOT_OFST: {
171 int64_t page = (
Value + Addend + 0x8000) & ~0xffff;
172 return (
Value + Addend - page) & 0xffff;
174 case ELF::R_MIPS_GPREL32: {
176 return Value + Addend - (GOTAddr + 0x7ff0);
178 case ELF::R_MIPS_PC16: {
180 return ((
Value + Addend - FinalAddress) >> 2) & 0xffff;
182 case ELF::R_MIPS_PC32: {
184 return Value + Addend - FinalAddress;
186 case ELF::R_MIPS_PC18_S3: {
188 return ((
Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
190 case ELF::R_MIPS_PC19_S2: {
192 return ((
Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
194 case ELF::R_MIPS_PC21_S2: {
196 return ((
Value + Addend - FinalAddress) >> 2) & 0x1fffff;
198 case ELF::R_MIPS_PC26_S2: {
200 return ((
Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
202 case ELF::R_MIPS_PCHI16: {
204 return ((
Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
206 case ELF::R_MIPS_PCLO16: {
208 return (
Value + Addend - FinalAddress) & 0xffff;
214 void RuntimeDyldELFMips::applyMIPSRelocation(uint8_t *TargetPtr, int64_t
Value,
222 case ELF::R_MIPS_GPREL16:
223 case ELF::R_MIPS_HI16:
224 case ELF::R_MIPS_LO16:
225 case ELF::R_MIPS_HIGHER:
226 case ELF::R_MIPS_HIGHEST:
227 case ELF::R_MIPS_PC16:
228 case ELF::R_MIPS_PCHI16:
229 case ELF::R_MIPS_PCLO16:
230 case ELF::R_MIPS_CALL16:
231 case ELF::R_MIPS_GOT_DISP:
232 case ELF::R_MIPS_GOT_PAGE:
233 case ELF::R_MIPS_GOT_OFST:
234 Insn = (Insn & 0xffff0000) | (
Value & 0x0000ffff);
237 case ELF::R_MIPS_PC18_S3:
238 Insn = (Insn & 0xfffc0000) | (
Value & 0x0003ffff);
241 case ELF::R_MIPS_PC19_S2:
242 Insn = (Insn & 0xfff80000) | (
Value & 0x0007ffff);
245 case ELF::R_MIPS_PC21_S2:
246 Insn = (Insn & 0xffe00000) | (
Value & 0x001fffff);
250 case ELF::R_MIPS_PC26_S2:
251 Insn = (Insn & 0xfc000000) | (
Value & 0x03ffffff);
255 case ELF::R_MIPS_GPREL32:
256 case ELF::R_MIPS_PC32:
260 case ELF::R_MIPS_SUB:
268 int64_t Addend, uint64_t SymOffset,
SID SectionID) {
269 int64_t CalculatedValue = evaluateMIPS64Relocation(
270 Section, Offset, Value, Type, Addend, SymOffset, SectionID);
277 int64_t Addend, uint64_t SymOffset,
SID SectionID) {
279 uint32_t r_type2 = (Type >> 8) & 0xff;
280 uint32_t r_type3 = (Type >> 16) & 0xff;
285 int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,
287 SymOffset, SectionID);
288 if (r_type2 != ELF::R_MIPS_NONE) {
290 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
291 CalculatedValue, SymOffset,
294 if (r_type3 != ELF::R_MIPS_NONE) {
296 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,
297 CalculatedValue, SymOffset,
314 <<
" Value: " <<
format(
"%x", Value) <<
" Type: " 315 <<
format(
"%x", Type) <<
" Addend: " <<
format(
"%x", Addend)
316 <<
" SymOffset: " <<
format(
"%x", Offset) <<
"\n");
318 Value = evaluateMIPS32Relocation(Section, Offset, Value, Type);
320 applyMIPSRelocation(TargetPtr, Value, Type);
RelocationEntry - used to represent relocations internally in the dynamic linker. ...
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
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.
size_t getGOTEntrySize() override
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
unsigned SectionID
SectionID - the section this relocation points to.
The instances of the Type class are immutable: once they are created, they are never changed...
DenseMap< SID, SID > SectionToGOTMap
uint8_t * getSectionAddress(unsigned SectionID) const
#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.
uint64_t getSectionLoadAddress(unsigned SectionID) const
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.
uint8_t * getAddressWithOffset(unsigned OffsetBytes) const
Return the address of this section with an offset.
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.