+#if SUPPORT_ARCH_arm64
+template <>
+void Section<arm64>::addLOH(class Parser<arm64>& parser, int kind, int count, const uint64_t addrs[]) {
+ switch (kind) {
+ case LOH_ARM64_ADRP_ADRP:
+ case LOH_ARM64_ADRP_LDR:
+ case LOH_ARM64_ADRP_ADD:
+ case LOH_ARM64_ADRP_LDR_GOT:
+ if ( count != 2 )
+ warning("arm64 Linker Optimiztion Hint %d has wrong number of arguments", kind);
+ break;
+ case LOH_ARM64_ADRP_ADD_LDR:
+ case LOH_ARM64_ADRP_LDR_GOT_LDR:
+ case LOH_ARM64_ADRP_ADD_STR:
+ case LOH_ARM64_ADRP_LDR_GOT_STR:
+ if ( count != 3 )
+ warning("arm64 Linker Optimiztion Hint %d has wrong number of arguments", kind);
+ }
+
+ // pick lowest address in tuple for use as offsetInAtom
+ uint64_t lowestAddress = addrs[0];
+ for(int i=1; i < count; ++i) {
+ if ( addrs[i] < lowestAddress )
+ lowestAddress = addrs[i];
+ }
+ // verify all other address are in same atom
+ Atom<arm64>* inAtom = parser.findAtomByAddress(lowestAddress);
+ const uint64_t atomStartAddr = inAtom->objectAddress();
+ const uint64_t atomEndAddr = atomStartAddr + inAtom->size();
+ for(int i=0; i < count; ++i) {
+ if ( (addrs[i] < atomStartAddr) || (addrs[i] >= atomEndAddr) ) {
+ warning("arm64 Linker Optimiztion Hint addresses are not in same atom: 0x%08llX and 0x%08llX",
+ lowestAddress, addrs[i]);
+ return; // skip this LOH
+ }
+ if ( (addrs[i] & 0x3) != 0 ) {
+ warning("arm64 Linker Optimiztion Hint address is not 4-byte aligned: 0x%08llX", addrs[i]);
+ return; // skip this LOH
+ }
+ if ( (addrs[i] - lowestAddress) > 0xFFFF ) {
+ if ( parser.verboseOptimizationHints() ) {
+ warning("arm64 Linker Optimiztion Hint addresses are too far apart: 0x%08llX and 0x%08llX",
+ lowestAddress, addrs[i]);
+ }
+ return; // skip this LOH
+ }
+ }
+
+ // encoded kind, count, and address deltas in 64-bit addend
+ ld::Fixup::LOH_arm64 extra;
+ extra.addend = 0;
+ extra.info.kind = kind;
+ extra.info.count = count-1;
+ extra.info.delta1 = (addrs[0] - lowestAddress) >> 2;
+ extra.info.delta2 = (count > 1) ? ((addrs[1] - lowestAddress) >> 2) : 0;
+ extra.info.delta3 = (count > 2) ? ((addrs[2] - lowestAddress) >> 2) : 0;
+ extra.info.delta4 = (count > 3) ? ((addrs[3] - lowestAddress) >> 2) : 0;
+ typename Parser<arm64>::SourceLocation src(inAtom, lowestAddress- inAtom->objectAddress());
+ parser.addFixup(src, ld::Fixup::k1of1, ld::Fixup::kindLinkerOptimizationHint, extra.addend);
+}
+#endif
+
+template <typename A>
+void Section<A>::addLOH(class Parser<A>& parser, int kind, int count, const uint64_t addrs[]) {
+
+}