12#define DEBUG_TYPE "dyld"
53RuntimeDyldELFMips::evaluateMIPS32Relocation(
const SectionEntry &Section,
59 <<
" FinalAddress: 0x"
61 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
72 case ELF::R_MIPS_HI16:
74 return (
Value + 0x8000) >> 16;
75 case ELF::R_MIPS_LO16:
77 case ELF::R_MIPS_PC32: {
79 return Value - FinalAddress;
81 case ELF::R_MIPS_PC16: {
83 return (
Value - FinalAddress) >> 2;
85 case ELF::R_MIPS_PC19_S2: {
87 return (
Value - (FinalAddress & ~0x3)) >> 2;
89 case ELF::R_MIPS_PC21_S2: {
91 return (
Value - FinalAddress) >> 2;
93 case ELF::R_MIPS_PC26_S2: {
95 return (
Value - FinalAddress) >> 2;
97 case ELF::R_MIPS_PCHI16: {
99 return (
Value - FinalAddress + 0x8000) >> 16;
101 case ELF::R_MIPS_PCLO16: {
103 return Value - FinalAddress;
108int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation(
110 int64_t Addend,
uint64_t SymOffset, SID SectionID) {
114 <<
" FinalAddress: 0x"
116 <<
" Value: 0x" <<
format(
"%llx",
Value) <<
" Type: 0x"
120 <<
" SID: " <<
format(
"%d", SectionID)
121 <<
" SymOffset: " <<
format(
"%x", SymOffset) <<
"\n");
127 case ELF::R_MIPS_JALR:
128 case ELF::R_MIPS_NONE:
132 return Value + Addend;
134 return ((
Value + Addend) >> 2) & 0x3ffffff;
135 case ELF::R_MIPS_GPREL16: {
137 return Value + Addend - (GOTAddr + 0x7ff0);
139 case ELF::R_MIPS_SUB:
140 return Value - Addend;
141 case ELF::R_MIPS_HI16:
143 return ((
Value + Addend + 0x8000) >> 16) & 0xffff;
144 case ELF::R_MIPS_LO16:
145 return (
Value + Addend) & 0xffff;
146 case ELF::R_MIPS_HIGHER:
147 return ((
Value + Addend + 0x80008000) >> 32) & 0xffff;
148 case ELF::R_MIPS_HIGHEST:
149 return ((
Value + Addend + 0x800080008000) >> 48) & 0xffff;
150 case ELF::R_MIPS_CALL16:
151 case ELF::R_MIPS_GOT_DISP:
152 case ELF::R_MIPS_GOT_PAGE: {
158 if (
Type == ELF::R_MIPS_GOT_PAGE)
163 "GOT entry has two different addresses.");
167 return (SymOffset - 0x7ff0) & 0xffff;
169 case ELF::R_MIPS_GOT_OFST: {
170 int64_t page = (
Value + Addend + 0x8000) & ~0xffff;
171 return (
Value + Addend - page) & 0xffff;
173 case ELF::R_MIPS_GPREL32: {
175 return Value + Addend - (GOTAddr + 0x7ff0);
177 case ELF::R_MIPS_PC16: {
179 return ((
Value + Addend - FinalAddress) >> 2) & 0xffff;
181 case ELF::R_MIPS_PC32: {
183 return Value + Addend - FinalAddress;
185 case ELF::R_MIPS_PC18_S3: {
187 return ((
Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
189 case ELF::R_MIPS_PC19_S2: {
191 return ((
Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
193 case ELF::R_MIPS_PC21_S2: {
195 return ((
Value + Addend - FinalAddress) >> 2) & 0x1fffff;
197 case ELF::R_MIPS_PC26_S2: {
199 return ((
Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
201 case ELF::R_MIPS_PCHI16: {
203 return ((
Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
205 case ELF::R_MIPS_PCLO16: {
207 return (
Value + Addend - FinalAddress) & 0xffff;
213void RuntimeDyldELFMips::applyMIPSRelocation(
uint8_t *TargetPtr, int64_t
Value,
221 case ELF::R_MIPS_GPREL16:
222 case ELF::R_MIPS_HI16:
223 case ELF::R_MIPS_LO16:
224 case ELF::R_MIPS_HIGHER:
225 case ELF::R_MIPS_HIGHEST:
226 case ELF::R_MIPS_PC16:
227 case ELF::R_MIPS_PCHI16:
228 case ELF::R_MIPS_PCLO16:
229 case ELF::R_MIPS_CALL16:
230 case ELF::R_MIPS_GOT_DISP:
231 case ELF::R_MIPS_GOT_PAGE:
232 case ELF::R_MIPS_GOT_OFST:
236 case ELF::R_MIPS_PC18_S3:
240 case ELF::R_MIPS_PC19_S2:
244 case ELF::R_MIPS_PC21_S2:
249 case ELF::R_MIPS_PC26_S2:
254 case ELF::R_MIPS_GPREL32:
255 case ELF::R_MIPS_PC32:
259 case ELF::R_MIPS_SUB:
267 int64_t Addend,
uint64_t SymOffset,
SID SectionID) {
268 int64_t CalculatedValue = evaluateMIPS64Relocation(
270 applyMIPSRelocation(Section.getAddressWithOffset(
Offset), CalculatedValue,
276 int64_t Addend,
uint64_t SymOffset,
SID SectionID) {
284 int64_t CalculatedValue = evaluateMIPS64Relocation(Section,
Offset,
Value,
286 SymOffset, SectionID);
287 if (r_type2 != ELF::R_MIPS_NONE) {
289 CalculatedValue = evaluateMIPS64Relocation(Section,
Offset, 0, RelType,
290 CalculatedValue, SymOffset,
293 if (r_type3 != ELF::R_MIPS_NONE) {
295 CalculatedValue = evaluateMIPS64Relocation(Section,
Offset, 0, RelType,
296 CalculatedValue, SymOffset,
299 applyMIPSRelocation(Section.getAddressWithOffset(
Offset), CalculatedValue,
311 << Section.getAddressWithOffset(
Offset) <<
" FinalAddress: "
312 <<
format(
"%p", Section.getLoadAddressWithOffset(
Offset))
319 applyMIPSRelocation(TargetPtr,
Value,
Type);
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RelocationEntry - used to represent relocations internally in the dynamic linker.
uint32_t RelType
RelType - relocation type.
uint64_t Offset
Offset - offset into the section.
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
unsigned SectionID
SectionID - the section this relocation points to.
void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset, SID SectionID)
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override
A object file specific relocation resolver.
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)
size_t getGOTEntrySize() override
DenseMap< SID, SID > SectionToGOTMap
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
uint64_t getSectionLoadAddress(unsigned SectionID) const
uint8_t * getSectionAddress(unsigned SectionID) const
SectionEntry - represents a section emitted into memory by the dynamic linker.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.