llvm.org GIT mirror llvm / 2a069ac
[RuntimeDyld] Support more PPC64 relocations This adds support for several missing PPC64 relocations in the straight-forward manner to RuntimeDyldELF.cpp. Note that this actually fixes a failure of a large-model test case on PowerPC, allowing the XFAIL to be removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211382 91177308-0d34-0410-b5e6-96231b3b80d8 Ulrich Weigand 6 years ago
2 changed file(s) with 71 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
701701 llvm_unreachable("Attempting to get address of ODP entry!");
702702 }
703703
704 // Relocation masks following the #lo(value), #hi(value), #higher(value),
705 // and #highest(value) macros defined in section 4.5.1. Relocation Types
706 // in PPC-elf64abi document.
707 //
704 // Relocation masks following the #lo(value), #hi(value), #ha(value),
705 // #higher(value), #highera(value), #highest(value), and #highesta(value)
706 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
707 // document.
708
708709 static inline uint16_t applyPPClo(uint64_t value) { return value & 0xffff; }
709710
710711 static inline uint16_t applyPPChi(uint64_t value) {
711712 return (value >> 16) & 0xffff;
712713 }
713714
715 static inline uint16_t applyPPCha (uint64_t value) {
716 return ((value + 0x8000) >> 16) & 0xffff;
717 }
718
714719 static inline uint16_t applyPPChigher(uint64_t value) {
715720 return (value >> 32) & 0xffff;
716721 }
717722
723 static inline uint16_t applyPPChighera (uint64_t value) {
724 return ((value + 0x8000) >> 32) & 0xffff;
725 }
726
718727 static inline uint16_t applyPPChighest(uint64_t value) {
719728 return (value >> 48) & 0xffff;
729 }
730
731 static inline uint16_t applyPPChighesta (uint64_t value) {
732 return ((value + 0x8000) >> 48) & 0xffff;
720733 }
721734
722735 void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
727740 default:
728741 llvm_unreachable("Relocation type not implemented yet!");
729742 break;
743 case ELF::R_PPC64_ADDR16:
744 writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
745 break;
746 case ELF::R_PPC64_ADDR16_DS:
747 writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
748 break;
730749 case ELF::R_PPC64_ADDR16_LO:
731750 writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
732751 break;
752 case ELF::R_PPC64_ADDR16_LO_DS:
753 writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
754 break;
733755 case ELF::R_PPC64_ADDR16_HI:
734756 writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
735757 break;
758 case ELF::R_PPC64_ADDR16_HA:
759 writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
760 break;
736761 case ELF::R_PPC64_ADDR16_HIGHER:
737762 writeInt16BE(LocalAddress, applyPPChigher(Value + Addend));
738763 break;
764 case ELF::R_PPC64_ADDR16_HIGHERA:
765 writeInt16BE(LocalAddress, applyPPChighera(Value + Addend));
766 break;
739767 case ELF::R_PPC64_ADDR16_HIGHEST:
740768 writeInt16BE(LocalAddress, applyPPChighest(Value + Addend));
769 break;
770 case ELF::R_PPC64_ADDR16_HIGHESTA:
771 writeInt16BE(LocalAddress, applyPPChighesta(Value + Addend));
741772 break;
742773 case ELF::R_PPC64_ADDR14: {
743774 assert(((Value + Addend) & 3) == 0);
744775 // Preserve the AA/LK bits in the branch instruction
745776 uint8_t aalk = *(LocalAddress + 3);
746777 writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
778 } break;
779 case ELF::R_PPC64_REL16_LO: {
780 uint64_t FinalAddress = (Section.LoadAddress + Offset);
781 uint64_t Delta = Value - FinalAddress + Addend;
782 writeInt16BE(LocalAddress, applyPPClo(Delta));
783 } break;
784 case ELF::R_PPC64_REL16_HI: {
785 uint64_t FinalAddress = (Section.LoadAddress + Offset);
786 uint64_t Delta = Value - FinalAddress + Addend;
787 writeInt16BE(LocalAddress, applyPPChi(Delta));
788 } break;
789 case ELF::R_PPC64_REL16_HA: {
790 uint64_t FinalAddress = (Section.LoadAddress + Offset);
791 uint64_t Delta = Value - FinalAddress + Addend;
792 writeInt16BE(LocalAddress, applyPPCha(Delta));
747793 } break;
748794 case ELF::R_PPC64_ADDR32: {
749795 int32_t Result = static_cast(Value + Addend);
785831 case ELF::R_PPC64_TOC16_DS: {
786832 uint64_t TOCStart = findPPC64TOC();
787833 Value = ((Value + Addend) - TOCStart);
834 writeInt16BE(LocalAddress, applyPPClo(Value) & ~3);
835 } break;
836 case ELF::R_PPC64_TOC16_LO: {
837 uint64_t TOCStart = findPPC64TOC();
838 Value = ((Value + Addend) - TOCStart);
788839 writeInt16BE(LocalAddress, applyPPClo(Value));
840 } break;
841 case ELF::R_PPC64_TOC16_LO_DS: {
842 uint64_t TOCStart = findPPC64TOC();
843 Value = ((Value + Addend) - TOCStart);
844 writeInt16BE(LocalAddress, applyPPClo(Value) & ~3);
845 } break;
846 case ELF::R_PPC64_TOC16_HI: {
847 uint64_t TOCStart = findPPC64TOC();
848 Value = ((Value + Addend) - TOCStart);
849 writeInt16BE(LocalAddress, applyPPChi(Value));
850 } break;
851 case ELF::R_PPC64_TOC16_HA: {
852 uint64_t TOCStart = findPPC64TOC();
853 Value = ((Value + Addend) - TOCStart);
854 writeInt16BE(LocalAddress, applyPPCha(Value));
789855 } break;
790856 }
791857 }
0 ; RUN: %lli_mcjit -relocation-model=pic -code-model=large %s
1 ; XFAIL: cygwin, win32, mingw, mips, powerpc64, i686, i386, aarch64, arm
1 ; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm
22 declare i8* @__cxa_allocate_exception(i64)
33 declare void @__cxa_throw(i8*, i8*, i8*)
44 declare i32 @__gxx_personality_v0(...)