Skip to content

Commit

Permalink
[widevine] add support for arm64
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
tmm1 committed Feb 10, 2023
1 parent 25b3da3 commit a9ba88e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ void CSession::SetSupportedDecrypterURN(std::string& key_system)
m_dllHelper = std::make_unique<kodi::tools::CDllHelper>();
if (m_dllHelper->LoadDll(item.Path()))
{
#if 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"))
{
Expand Down
66 changes: 66 additions & 0 deletions wvdecrypter/wvdecrypter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <thread>
#include <vector>

#if defined(__aarch64__) && !defined(ANDROID)
#include <sys/auxv.h>
#endif
#include <bento4/Ap4.h>

#ifndef WIDEVINECDMFILENAME
Expand Down Expand Up @@ -1671,6 +1674,69 @@ class WVDecrypter : public SSD_DECRYPTER

extern "C" {

// Linux arm64 version of libwidevinecdm.so depends on two
// dynamic symbols. See https:/xbmc/inputstream.adaptive/issues/1128
// These implementations are based on libgcc.a lse.S
#if 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
Expand Down

0 comments on commit a9ba88e

Please sign in to comment.