diff --git a/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/patches/001-add-aarch64-widevine-support.patch b/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/patches/001-add-aarch64-widevine-support.patch new file mode 100644 index 0000000000..b92355141e --- /dev/null +++ b/packages/mediacenter/kodi-binary-addons/inputstream.adaptive/patches/001-add-aarch64-widevine-support.patch @@ -0,0 +1,215 @@ +From 582ae9559c74288f488313c2b3a737e9fc1c6715 Mon Sep 17 00:00:00 2001 +From: Aman Karmani +Date: Thu, 9 Feb 2023 17:04:28 -0800 +Subject: [PATCH 1/2] [widevine] add support for linux arm64 + +without these changes, the following error is observed: + + Initialize: Failed to load library: libwidevinecdm.so: undefined symbol: __aarch64_ldadd4_acq_rel + Unable to load widevine shared library (libwidevinecdm.so) +--- + src/Session.cpp | 13 ++++++++ + wvdecrypter/wvdecrypter.cpp | 66 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 79 insertions(+) + +diff --git a/src/Session.cpp b/src/Session.cpp +index db16866c..21988b7e 100644 +--- a/src/Session.cpp ++++ b/src/Session.cpp +@@ -140,6 +140,19 @@ void CSession::SetSupportedDecrypterURN(std::string& key_system) + m_dllHelper = std::make_unique(); + if (m_dllHelper->LoadDll(item.Path())) + { ++#if defined(__linux__) && defined(__aarch64__) && !defined(ANDROID) ++ // On linux arm64, libwidevinecdm.so depends on two dynamic symbols: ++ // __aarch64_ldadd4_acq_rel ++ // __aarch64_swp4_acq_rel ++ // These are defined in libssd_wv.so, but to make them available in the main binary's PLT, ++ // we need RTLD_GLOBAL. LoadDll() above uses RTLD_LOCAL, so we use RTLD_NOLOAD here to ++ // switch the flags from LOCAL to GLOBAL. ++ void *hdl = dlopen(item.Path().c_str(), RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY); ++ if (!hdl) ++ { ++ LOG::Log(LOGERROR, "Failed to reload dll in global mode: %s", dlerror()); ++ } ++#endif + CreateDecryptorInstanceFunc startup; + if (m_dllHelper->RegisterSymbol(startup, "CreateDecryptorInstance")) + { +diff --git a/wvdecrypter/wvdecrypter.cpp b/wvdecrypter/wvdecrypter.cpp +index 927b3715..68ce8959 100644 +--- a/wvdecrypter/wvdecrypter.cpp ++++ b/wvdecrypter/wvdecrypter.cpp +@@ -23,6 +23,9 @@ + #include + #include + ++#if defined(__linux__) && defined(__aarch64__) && !defined(ANDROID) ++#include ++#endif + #include + + #ifndef WIDEVINECDMFILENAME +@@ -1671,6 +1674,69 @@ class WVDecrypter : public SSD_DECRYPTER + + extern "C" { + ++// Linux arm64 version of libwidevinecdm.so depends on two ++// dynamic symbols. See https://github.com/xbmc/inputstream.adaptive/issues/1128 ++// These implementations are based on libgcc.a lse.S ++#if defined(__linux__) && defined(__aarch64__) && !defined(ANDROID) ++static int have_lse_atomics; ++ ++static void __attribute__((constructor (101))) init_have_lse_atomics() ++{ ++ unsigned long hwcap = getauxval (AT_HWCAP); ++ have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0; ++} ++ ++int32_t __aarch64_ldadd4_acq_rel(int32_t value, int32_t *ptr) ++{ ++ int32_t ret; ++ if (have_lse_atomics) { ++ __asm__ __volatile__ ( ++ ".inst 0x38200020 + 0x0000 + 0x80000000 + 0xc00000\r\n" ++ : "=&r" (ret) ++ : ++ ); ++ } else { ++ __asm__ __volatile__ ( ++ "0:\r\n" ++ "ldaxr w16, [%[ptr]]\r\n" ++ "add w17, w16, %w[value]\r\n" ++ "stlxr w15, w17, [%[ptr]]\r\n" ++ "cbnz w15, 0b\r\n" ++ "mov %w[result], w16\r\n" ++ : [result] "=&r" (ret) ++ : [ptr] "r" (ptr), ++ [value] "r" (value) ++ : "w15", "w16", "w17", "memory" ++ ); ++ } ++ return ret; ++} ++ ++int32_t __aarch64_swp4_acq_rel(int32_t value, int32_t *ptr) ++{ ++ int32_t ret; ++ if (have_lse_atomics) { ++ __asm__ __volatile__ ( ++ ".inst 0x38208020 + 0x80000000 + 0xc00000\r\n" ++ : "=&r" (ret) ++ : ++ ); ++ } else { ++ __asm__ __volatile__ ( ++ "0:\r\n" ++ "ldaxr %w[result], [%[ptr]]\r\n" ++ "stlxr w15, %w[value], [%[ptr]]\r\n" ++ "cbnz w15, 0b\r\n" ++ : [result] "=&r" (ret) ++ : [ptr] "r" (ptr), ++ [value] "r" (value) ++ : "w15", "memory" ++ ); ++ } ++ return ret; ++} ++#endif ++ + #ifdef _WIN32 + #define MODULE_API __declspec(dllexport) + #else + +From 620e8eed7b662c7b125c2b96397d88e0572ed750 Mon Sep 17 00:00:00 2001 +From: Aman Karmani +Date: Fri, 10 Feb 2023 08:06:28 -0800 +Subject: [PATCH 2/2] [widevine] reimplement linux arm64 helpers without ASM + +--- + wvdecrypter/wvdecrypter.cpp | 58 +++---------------------------------- + 1 file changed, 4 insertions(+), 54 deletions(-) + +diff --git a/wvdecrypter/wvdecrypter.cpp b/wvdecrypter/wvdecrypter.cpp +index 68ce8959..ccb4936d 100644 +--- a/wvdecrypter/wvdecrypter.cpp ++++ b/wvdecrypter/wvdecrypter.cpp +@@ -23,9 +23,6 @@ + #include + #include + +-#if defined(__linux__) && defined(__aarch64__) && !defined(ANDROID) +-#include +-#endif + #include + + #ifndef WIDEVINECDMFILENAME +@@ -1676,64 +1673,17 @@ extern "C" { + + // Linux arm64 version of libwidevinecdm.so depends on two + // dynamic symbols. See https://github.com/xbmc/inputstream.adaptive/issues/1128 +-// These implementations are based on libgcc.a lse.S + #if defined(__linux__) && defined(__aarch64__) && !defined(ANDROID) +-static int have_lse_atomics; +- +-static void __attribute__((constructor (101))) init_have_lse_atomics() +-{ +- unsigned long hwcap = getauxval (AT_HWCAP); +- have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0; +-} +- ++__attribute__((target("no-outline-atomics"))) + int32_t __aarch64_ldadd4_acq_rel(int32_t value, int32_t *ptr) + { +- int32_t ret; +- if (have_lse_atomics) { +- __asm__ __volatile__ ( +- ".inst 0x38200020 + 0x0000 + 0x80000000 + 0xc00000\r\n" +- : "=&r" (ret) +- : +- ); +- } else { +- __asm__ __volatile__ ( +- "0:\r\n" +- "ldaxr w16, [%[ptr]]\r\n" +- "add w17, w16, %w[value]\r\n" +- "stlxr w15, w17, [%[ptr]]\r\n" +- "cbnz w15, 0b\r\n" +- "mov %w[result], w16\r\n" +- : [result] "=&r" (ret) +- : [ptr] "r" (ptr), +- [value] "r" (value) +- : "w15", "w16", "w17", "memory" +- ); +- } +- return ret; ++ return __atomic_fetch_add(ptr, value, __ATOMIC_ACQ_REL); + } + ++__attribute__((target("no-outline-atomics"))) + int32_t __aarch64_swp4_acq_rel(int32_t value, int32_t *ptr) + { +- int32_t ret; +- if (have_lse_atomics) { +- __asm__ __volatile__ ( +- ".inst 0x38208020 + 0x80000000 + 0xc00000\r\n" +- : "=&r" (ret) +- : +- ); +- } else { +- __asm__ __volatile__ ( +- "0:\r\n" +- "ldaxr %w[result], [%[ptr]]\r\n" +- "stlxr w15, %w[value], [%[ptr]]\r\n" +- "cbnz w15, 0b\r\n" +- : [result] "=&r" (ret) +- : [ptr] "r" (ptr), +- [value] "r" (value) +- : "w15", "memory" +- ); +- } +- return ret; ++ return __atomic_exchange_n(ptr, value, __ATOMIC_ACQ_REL); + } + #endif +