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: {
 
   78    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   79    return Value - FinalAddress;
 
   81  case ELF::R_MIPS_PC16: {
 
   82    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   83    return (
Value - FinalAddress) >> 2;
 
   85  case ELF::R_MIPS_PC19_S2: {
 
   86    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   87    return (
Value - (FinalAddress & ~0x3)) >> 2;
 
   89  case ELF::R_MIPS_PC21_S2: {
 
   90    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   91    return (
Value - FinalAddress) >> 2;
 
   93  case ELF::R_MIPS_PC26_S2: {
 
   94    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   95    return (
Value - FinalAddress) >> 2;
 
   97  case ELF::R_MIPS_PCHI16: {
 
   98    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
   99    return (
Value - FinalAddress + 0x8000) >> 16;
 
  101  case ELF::R_MIPS_PCLO16: {
 
  102    uint32_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  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: {
 
  153    uint8_t *LocalGOTAddr =
 
  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: {
 
  178    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  179    return ((
Value + Addend - FinalAddress) >> 2) & 0xffff;
 
  181  case ELF::R_MIPS_PC32: {
 
  182    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  183    return Value + Addend - FinalAddress;
 
  185  case ELF::R_MIPS_PC18_S3: {
 
  186    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  187    return ((
Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;
 
  189  case ELF::R_MIPS_PC19_S2: {
 
  190    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  191    return ((
Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
 
  193  case ELF::R_MIPS_PC21_S2: {
 
  194    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  195    return ((
Value + Addend - FinalAddress) >> 2) & 0x1fffff;
 
  197  case ELF::R_MIPS_PC26_S2: {
 
  198    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  199    return ((
Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
 
  201  case ELF::R_MIPS_PCHI16: {
 
  202    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  203    return ((
Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
 
  205  case ELF::R_MIPS_PCLO16: {
 
  206    uint64_t FinalAddress = 
Section.getLoadAddressWithOffset(
Offset);
 
  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:
 
  233    Insn = (Insn & 0xffff0000) | (
Value & 0x0000ffff);
 
  236  case ELF::R_MIPS_PC18_S3:
 
  237    Insn = (Insn & 0xfffc0000) | (
Value & 0x0003ffff);
 
  240  case ELF::R_MIPS_PC19_S2:
 
  241    Insn = (Insn & 0xfff80000) | (
Value & 0x0007ffff);
 
  244  case ELF::R_MIPS_PC21_S2:
 
  245    Insn = (Insn & 0xffe00000) | (
Value & 0x001fffff);
 
  249  case ELF::R_MIPS_PC26_S2:
 
  250    Insn = (Insn & 0xfc000000) | (
Value & 0x03ffffff);
 
  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);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
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.
 
FunctionAddr VTableAddr Value
 
LLVM_ABI 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.