Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tackle mcode_alloc issues once and for all #283

Merged
merged 100 commits into from
Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
e8e8785
Switch to amalgam LuaJIT builds, like on other platforms
NiLuJe Dec 27, 2020
27ee89e
Use the same soname as other platforms
NiLuJe Dec 27, 2020
32e8354
Switch LuaJIT to a sherd prebuilt lib
NiLuJe Dec 27, 2020
6dfb4f2
Make the Android build-system happy
NiLuJe Dec 27, 2020
190db5c
Make sure we bundle luajit as libluajit.so, to match its soname...
NiLuJe Dec 27, 2020
e7df39f
Oops
NiLuJe Dec 27, 2020
2e2ff08
Which means the much simpler approach works, once I don't have broken
NiLuJe Dec 27, 2020
83b1d7e
Progress :)
NiLuJe Dec 27, 2020
280c55a
Okay, it builds, but no longer ships the prebuilt o_O
NiLuJe Dec 27, 2020
4760921
Well, that's dumb.
NiLuJe Dec 27, 2020
4c8edf0
Actually dlopen the thing now ;p
NiLuJe Dec 27, 2020
8abecb6
Load the right entry point
NiLuJe Dec 27, 2020
c2e5b31
Do the dlsym dance...
NiLuJe Dec 27, 2020
15ed66f
Muahahahahaha
NiLuJe Dec 27, 2020
13c5c23
Cache the C namespace
NiLuJe Dec 27, 2020
686abed
Better comment
NiLuJe Dec 27, 2020
a728b23
Unify Android.mk syntax
NiLuJe Dec 27, 2020
b03f097
Update comments
NiLuJe Dec 27, 2020
adc6143
We should no longer have to disable the JIT at all...
NiLuJe Dec 27, 2020
8b805e6
Update that comment, too
NiLuJe Dec 27, 2020
de49a9b
Don't use pairs in the loader hack
NiLuJe Dec 27, 2020
abf161f
Actually do what the comment says?
NiLuJe Dec 27, 2020
de3f99e
Update comments, and actually implement the "lib already loaded"
NiLuJe Dec 27, 2020
38dc9a6
Load required libraries (not the DT_NEEDED ones) into the global
NiLuJe Dec 27, 2020
a3c3399
Don't reload the libc, either
NiLuJe Dec 27, 2020
8e721d3
Pass RTLD_LAZY explicitly
NiLuJe Dec 27, 2020
1a2d770
Not quite sure why the RTLD_GLOBAL stuff fails with unsupported flags,
NiLuJe Dec 27, 2020
dceb9f1
Oh, bionic...
NiLuJe Dec 27, 2020
57be560
That's slightly less broken
NiLuJe Dec 27, 2020
2fe1cc9
More comments
NiLuJe Dec 27, 2020
3cc4dd4
Comment tweaks
NiLuJe Dec 28, 2020
94dbfef
Hmm, that might be a problem...
NiLuJe Dec 28, 2020
74c69f3
Mangle dl.lua some more...
NiLuJe Dec 28, 2020
e020520
Get rid of the mostly useless already loaded check
NiLuJe Dec 28, 2020
9988aab
Well, why this blows up in fun and interesting ways with the JIT enabled
NiLuJe Dec 28, 2020
b71646e
Hmm, the fact that RTLD_NOW is 0 on LP32 means this was effectively what
NiLuJe Dec 28, 2020
4b9a340
Tone down logging, and get rid of the libc exceptions, as they don't
NiLuJe Dec 28, 2020
77f5173
Tweak that comment a bit
NiLuJe Dec 28, 2020
8a9467b
Simplify the libandroid/liblog/glue loading to hide the implementation
NiLuJe Dec 28, 2020
b85fb07
mmap tuning
NiLuJe Dec 28, 2020
0181e7b
Hmm, defaults appear to be more solid...
NiLuJe Dec 28, 2020
e8003d2
More accurate comment
NiLuJe Dec 28, 2020
719be95
Get rid of the libluajit exception
NiLuJe Dec 28, 2020
1aaed4a
Play with dl logging to make the dependency tree slightly more visual
NiLuJe Dec 28, 2020
4077ef3
More log tweaking, and a clarification on the system lib exclusion
NiLuJe Dec 28, 2020
2e9d5a8
Make that more lddtree'esque
NiLuJe Dec 28, 2020
6891046
Drop redundant log message
NiLuJe Dec 28, 2020
0e5442c
Okay, more readable logging confirmed that the loops are breaking early
NiLuJe Dec 28, 2020
6f7b73d
Link to the final commit that actually had this code in ;)
NiLuJe Dec 28, 2020
36e8c74
Expand on that coment some more
NiLuJe Dec 28, 2020
d35847b
Okay, git blame is my friend
NiLuJe Dec 28, 2020
e01dfdf
Minor review pass
NiLuJe Dec 28, 2020
2daa8cd
mmap size tuning
NiLuJe Dec 28, 2020
aa8d492
For posterity's sake ;p
NiLuJe Dec 28, 2020
9c2d6df
Let's double-check on a release build...
NiLuJe Dec 29, 2020
e061271
Log the address of a LuaJIT symbol to confirm whether we were mapped
NiLuJe Dec 29, 2020
1d24676
That looks fine in a release build...
NiLuJe Dec 29, 2020
226fc5e
This is a horrible hack.
NiLuJe Dec 30, 2020
40ad417
Forgot the LuaJIT bits in previous commit
NiLuJe Dec 30, 2020
6771962
The validptr makes no sense in our context
NiLuJe Dec 30, 2020
2d72167
Let's see what happens if we don't free on flush, and instead just clear
NiLuJe Dec 30, 2020
2d999f5
Only use MAP_FIXED for actual mappings of the reserved region (i.e., the
NiLuJe Dec 30, 2020
3b3aa1c
Unbreak build
NiLuJe Dec 30, 2020
c05a993
WIP don't free on flush
NiLuJe Dec 30, 2020
a4f16e7
Less verbose logging
NiLuJe Dec 30, 2020
073f378
Much better crazy hack, now that we've got the "flush won't remap" thing
NiLuJe Dec 30, 2020
26777d8
Cleaned things up a bit, got rid of the mcode hacks in the C launcher
NiLuJe Dec 30, 2020
8d3ebee
More comments
NiLuJe Dec 30, 2020
9e8a39a
In the highly unlikely event the reserve doesn't fit the jumprange
NiLuJe Dec 30, 2020
1e28043
More comments
NiLuJe Dec 31, 2020
70480f3
Restore the mmap wroakround, it does help on *some* API levels...
NiLuJe Dec 31, 2020
18ff828
See if not using MAP_NORESERVE helps on those finicky API levels...
NiLuJe Dec 31, 2020
b59b6bd
Drop the !POSIX hunks, this is very much an Android hack ;p
NiLuJe Dec 31, 2020
fdcf70c
Comment style
NiLuJe Dec 31, 2020
a119d16
Resync LuaJIT w/ KOReader
NiLuJe Dec 31, 2020
4eaf8f2
Fix warning
NiLuJe Dec 31, 2020
57250e3
Make dlopen'ing LuaJIT optional
NiLuJe Dec 31, 2020
d7ff518
The final LuaJIT patches mean we no lnger need to dlopen it,
NiLuJe Dec 31, 2020
738882e
Split the LuaJIT patches in two, to get rid of the extra logging in
NiLuJe Dec 31, 2020
f33cea1
Actually split the patches ;)
NiLuJe Dec 31, 2020
bfbd0a9
Don't need that header when not dlopening LuaJIT
NiLuJe Dec 31, 2020
8a8e915
Fix patches
NiLuJe Dec 31, 2020
543dc5b
Revert "Fix patches"
NiLuJe Dec 31, 2020
dba4bc2
Tackle that the other way around, to make maintenance slightly less
NiLuJe Dec 31, 2020
b89f74b
Take two
NiLuJe Dec 31, 2020
08d91c4
Handle non-contiguous mcode areas properly in mcode_clear
NiLuJe Jan 1, 2021
db0e130
Refresh debug patch
NiLuJe Jan 1, 2021
6d699fa
Fix non-Android branch of the debug patch
NiLuJe Jan 1, 2021
d64284a
Add debugging around mprotect calls
NiLuJe Jan 1, 2021
d9630fd
Even more logging
NiLuJe Jan 1, 2021
61e59f7
Unbreak lj_mcode_clear
NiLuJe Jan 1, 2021
5d3bee4
Fix patches
NiLuJe Jan 1, 2021
14ec951
Better handling of the MCLink struct
NiLuJe Jan 1, 2021
a4156b4
Really fix the patches
NiLuJe Jan 1, 2021
89cbd58
Zap debug hack
NiLuJe Jan 1, 2021
b97f073
Double-check link clears
NiLuJe Jan 1, 2021
91c163e
Minor formatting tweak
NiLuJe Jan 1, 2021
bc419f3
Fix lastmcarea, and make sure mcode_clear handles chunked mcareas
NiLuJe Jan 2, 2021
e79e3d7
Minor logging tweak
NiLuJe Jan 2, 2021
22668f5
Review pass
NiLuJe Jan 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,15 @@ update:
@echo "using sdk in path $(ANDROID_SDK_FULLPATH)"
@echo "using ndk in path $(ANDROID_NDK_FULLPATH)"

build-luajit-debug:
@echo "Building LuaJIT for $(ANDROID_FULL_ARCH) (debug)"
cd jni/luajit && \
./mk-luajit.sh "$(ANDROID_FULL_ARCH)" "debug"

build-luajit:
@echo "Building LuaJIT for $(ANDROID_FULL_ARCH)"
cd jni/luajit && \
./mk-luajit.sh $(ANDROID_FULL_ARCH)
./mk-luajit.sh "$(ANDROID_FULL_ARCH)"

prepare: update
@echo "Building LuaJIT for all supported ABIs"
Expand All @@ -90,7 +95,7 @@ prepare: update
./mk-luajit.sh clean && \
./mk-luajit.sh armeabi-v7a

debug: update build-luajit
debug: update build-luajit-debug
@echo "Building $(APPNAME) debug APK: Version $(NAME), release $(VERSION), flavor $(FLAVOR)"
./gradlew -PversName=$(NAME) -PversCode=$(VERSION) -PprojectName=$(APPNAME) app:$(BUILD_TASK)Debug
mkdir -p bin/
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
android:screenOrientation="nosensor"
android:launchMode="singleInstance"
android:configChanges="colorMode|density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" >
<meta-data android:name="android.app.lib_name" android:value="luajit" />
<meta-data android:name="android.app.lib_name" android:value="luajit-launcher" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand Down
64 changes: 38 additions & 26 deletions assets/android.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ Java Native Interface (JNI) wrapper.
-- Attempt to grab the full maxmcode region in one go on startup,
-- to avoid mcode_alloc failures later on at runtime...
-- c.f., https://www.freelists.org/post/luajit/Android-performance-drop-moving-from-LuaJIT201-LuaJIT202
-- The other workaround mentioned earlier in that thread would require moving to a shared LuaJIT build,
-- and move the mmap hackery in jni/android-main.c before a dlopen of the luaJIT lib...
-- Without it, the most reliable results we can get are with a *single* 64K mcode block:
-- trying that with a single 512K block (as that's the default maxmcode) doesn't yield great results...
-- For optimal behavior, this relies on a few LuaJIT hacks:
-- * Ensuring a flush doesn't unmap the mcarea, but only clears it,
-- because when the mcarea is filled, LuaJIT flushes it,
-- and the Lua blitter can happily require more than 256K to flip a CRe page,
-- so flushes are common.
-- * Reserving a 1MB area inside LuaJIT's address space via a global array
-- * Making the first mcode_alloc use the address of this global via MAP_FIXED
-- c.f., koreader-luajit-mcode-reserve-hack.patch
-- Upstream issue: https://github.com/LuaJIT/LuaJIT/issues/285

-- Hope that forcing the allocation of a 64K segment in two blocks *right now* will succeed...
jit.opt.start("sizemcode=32", "maxmcode=64")
-- Given that, force the allocation of a single 512K segment *right now*.
-- (LuaJIT defaults are 32, 512 on 32-bit platforms, and 64, 512 otherwise).
jit.opt.start("sizemcode=512", "maxmcode=512")
-- This ensures a trace is generated, which requires an mcarea alloc ;).
for _ = 1, 100 do end

-- Disable the JIT for now, we'll enable it again when actually starting KOReader.
jit.off(true, true)

local ffi = require("ffi")

ffi.cdef[[
Expand Down Expand Up @@ -1137,16 +1140,17 @@ void AConfiguration_getCountry(AConfiguration* config, char* outCountry);
]]

-- JNI Interfacing
local C = ffi.C

local JNI = {}

function JNI:context(jvm, runnable)
self.jvm = jvm

local env = ffi.new("JNIEnv*[1]")
self.jvm[0].GetEnv(self.jvm, ffi.cast("void**", env), ffi.C.JNI_VERSION_1_6)
self.jvm[0].GetEnv(self.jvm, ffi.cast("void**", env), C.JNI_VERSION_1_6)

assert(self.jvm[0].AttachCurrentThread(self.jvm, env, nil) ~= ffi.C.JNI_ERR,
assert(self.jvm[0].AttachCurrentThread(self.jvm, env, nil) ~= C.JNI_ERR,
"cannot attach JVM to current thread")

self.env = env[0]
Expand Down Expand Up @@ -1191,15 +1195,15 @@ function JNI:callBooleanMethod(object, method, signature, ...)
local clazz = self.env[0].GetObjectClass(self.env, object)
local methodID = self.env[0].GetMethodID(self.env, clazz, method, signature)
self.env[0].DeleteLocalRef(self.env, clazz)
return self.env[0].CallBooleanMethod(self.env, object, methodID, ...) == ffi.C.JNI_TRUE
return self.env[0].CallBooleanMethod(self.env, object, methodID, ...) == C.JNI_TRUE
end

function JNI:callStaticBooleanMethod(class, method, signature, ...)
local clazz = self.env[0].FindClass(self.env, class)
local methodID = self.env[0].GetStaticMethodID(self.env, clazz, method, signature)
local res = self.env[0].CallStaticBooleanMethod(self.env, clazz, methodID, ...)
self.env[0].DeleteLocalRef(self.env, clazz)
return res == ffi.C.JNI_TRUE
return res == C.JNI_TRUE
end

function JNI:callObjectMethod(object, method, signature, ...)
Expand Down Expand Up @@ -1249,38 +1253,46 @@ end

-- Android specific

-- Some Android roms won't load libandroid.so to the global namespace thus
-- we load it by ourselves.
-- We need to load libandroid, liblog, and the app glue: they're no longer in the global namespace
-- as we're now running under a plain LuaJIT.
-- NOTE: We haven't overloaded fii.load yet
-- (and we can't, as our custom implementation depends on libandroid and liblog for logging ^^),
-- so, we hope that the fact we've kept linking libluajit-launcher against libandroid and liblog will be enough
-- to satisfy old and broken platforms where dlopen is extra finicky...
local android_lib_ok, android_lib = pcall(ffi.load, "libandroid.so")
local android_log_ok, android_log = pcall(ffi.load, "liblog.so")
local android_glue_ok, android_glue = pcall(ffi.load, "libluajit-launcher.so")
local android = {
app = nil,
jni = JNI,
log_name = "luajit-launcher",
lib = android_lib_ok and android_lib or ffi.C,
lib = android_lib_ok and android_lib or C,
log = android_log_ok and android_log or C,
glue = android_glue_ok and android_glue or C,
}

function android.LOG(level, message)
ffi.C.__android_log_print(level, android.log_name, "%s", message)
android.log.__android_log_print(level, android.log_name, "%s", message)
end

function android.LOGVV(tag, message)
ffi.C.__android_log_print(ffi.C.ANDROID_LOG_VERBOSE, tag, "%s", message)
android.log.__android_log_print(C.ANDROID_LOG_VERBOSE, tag, "%s", message)
end

function android.LOGV(message)
android.LOG(ffi.C.ANDROID_LOG_VERBOSE, message)
android.LOG(C.ANDROID_LOG_VERBOSE, message)
end
function android.LOGD(message)
android.LOG(ffi.C.ANDROID_LOG_DEBUG, message)
android.LOG(C.ANDROID_LOG_DEBUG, message)
end
function android.LOGI(message)
android.LOG(ffi.C.ANDROID_LOG_INFO, message)
android.LOG(C.ANDROID_LOG_INFO, message)
end
function android.LOGW(message)
android.LOG(ffi.C.ANDROID_LOG_WARN, message)
android.LOG(C.ANDROID_LOG_WARN, message)
end
function android.LOGE(message)
android.LOG(ffi.C.ANDROID_LOG_ERROR, message)
android.LOG(C.ANDROID_LOG_ERROR, message)
end

--[[--
Expand All @@ -1296,7 +1308,7 @@ function android.asset_loader(modulename)
local filename = string.gsub("?.lua", "%?", modulepath)
local asset = android.lib.AAssetManager_open(
android.app.activity.assetManager,
filename, ffi.C.AASSET_MODE_BUFFER)
filename, C.AASSET_MODE_BUFFER)
--android.LOGI(string.format("trying to open asset %s: %s", filename, tostring(asset)))
if asset ~= nil then
-- read asset:
Expand Down Expand Up @@ -1774,8 +1786,8 @@ local function run(android_app_state)
end)
end,
set = function(new_orientation)
if new_orientation >= ffi.C.ASCREEN_ORIENTATION_UNSPECIFIED and
new_orientation <= ffi.C.ASCREEN_ORIENTATION_FULL_SENSOR then
if new_orientation >= C.ASCREEN_ORIENTATION_UNSPECIFIED and
new_orientation <= C.ASCREEN_ORIENTATION_FULL_SENSOR then
JNI:context(android.app.activity.vm, function(jni)
jni:callVoidMethod(
android.app.activity.clazz,
Expand Down
121 changes: 79 additions & 42 deletions assets/dl.lua
Original file line number Diff line number Diff line change
@@ -1,73 +1,95 @@
--[[
A LuaJIT FFI based version of dlopen() which loads dependencies
first (for implementations of dlopen() lacking that feature, like
on Android)
on Android before API 23,
c.f., https://android.googlesource.com/platform/bionic/+/refs/heads/master/android-changes-for-ndk-developers.md)

This is heavily inspired by the lo_dlopen() implementation from
LibreOffice (see
http://cgit.freedesktop.org/libreoffice/core/tree/sal/android/lo-bootstrap.c)
https://cgit.freedesktop.org/libreoffice/core/tree/sal/android/lo-bootstrap.c?id=963c98a65e4eddf179e170ff0bb30e4bfafc6b16)
and as such:

* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
--]]

-- Disable the JIT in this module, in an attempt to avoid weird issues when loading libraries
-- Disable the JIT in this module, to avoid weird and mysterious issues with dlopen (here and in ffi.load),
-- as well as the nested loops in dl.dlopen mysteriously breaking early.
jit.off(true, true)

local ffi = require("ffi")
local A = require("android")
local Elf = require("elf")
local log = "dlopen"

ffi.cdef[[
void *dlopen(const char *filename, int flag);
char *dlerror(void);
const static int RTLD_LOCAL = 0;
const static int RTLD_GLOBAL = 0x00100;
]]
local C = ffi.C

-- There's a bit of heinous hackery going on on 32-bit ABIs with RTLD_NOW & RTLD_GLOBAL...
-- c.f., https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/include/dlfcn.h
if jit.arch:sub(-2) == "64" then
ffi.cdef[[
void *dlopen(const char *filename, int flag);
char *dlerror(void);
const static int RTLD_LOCAL = 0;
const static int RTLD_LAZY = 0x00001;
const static int RTLD_NOW = 0x00002;
const static int RTLD_NOLOAD = 0x00004;
const static int RTLD_GLOBAL = 0x00100;
const static int RTLD_NODELETE = 0x01000;
]]
else
ffi.cdef[[
void *dlopen(const char *filename, int flag);
char *dlerror(void);
const static int RTLD_LOCAL = 0;
const static int RTLD_LAZY = 0x00001;
const static int RTLD_NOW = 0x00000;
const static int RTLD_NOLOAD = 0x00004;
const static int RTLD_GLOBAL = 0x00002;
const static int RTLD_NODELETE = 0x01000;
]]
end

local dl = {
-- set this to search in certain directories
library_path = '/lib/?;/usr/lib/?;/usr/local/lib/?',

loaded_libraries = {}
}

local function sys_dlopen(library)
A.LOGVV(log, string.format("sys_dlopen - loading library %s", library))
local p = ffi.C.dlopen(library, ffi.C.RTLD_LOCAL)
local function sys_dlopen(library, global, padding)
A.LOGVV(log, string.format("%"..padding.."ssys_dlopen - loading library %s (in %s namespace)", "", library, global and "global" or "local"))
local p = C.dlopen(library, bit.bor(C.RTLD_NOW, global and C.RTLD_GLOBAL or C.RTLD_LOCAL))
if p == nil then
local err_msg = ffi.C.dlerror()
local err_msg = C.dlerror()
if err_msg ~= nil then
error("error opening "..library..": "..ffi.string(err_msg))
end
else
C.dlerror()
end
return p
end

--[[
open_func will be used to load the library (but not its dependencies!)
load_func will be used to load the library (but not its dependencies!)
if not given, the system's dlopen() will be used

if the library name is an absolute path (starting with "/"), then
the library_path will not be used
--]]
function dl.dlopen(library, load_func)
-- check if we already opened it:
if dl.loaded_libraries[library] then return dl.loaded_libraries[library] end

function dl.dlopen(library, load_func, depth)
load_func = load_func or sys_dlopen
depth = depth or 0
local padding = depth * 4

for pspec in string.gmatch(
library:sub(1,1) == "/" and "" or dl.library_path,
library:sub(1, 1) == "/" and "" or dl.library_path,
"([^;:]+)") do

local lname, matches = string.gsub(pspec, "%?", library)
if matches == 0 then
-- if pathspec does not contain a '?', we do append
-- the library name to the pathspec
-- if pathspec does not contain a '?',
-- we append the library name to the pathspec
lname = lname .. '/' .. library
end

Expand All @@ -77,29 +99,44 @@ function dl.dlopen(library, load_func)
ok, lib = pcall(Elf.open, lname)
end
if ok then
A.LOGVV(log, string.format("dl.dlopen - library lname detected %s", lname))
A.LOGVV(log, string.format("%"..padding.."sdl.dlopen - %s => %s", "", library, lname))
-- Skip loading system libraries (unless we explicitly asked for one, in which case, that's on the caller ;)).
-- c.f., https://github.com/koreader/android-luajit-launcher/pull/69
-- Note that, technically, for Android >= 6.0, the list of safe system libraries is:
-- libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics,
-- liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++,
-- libvulkan, and libz
-- Our current code should *never* hit any non-whitelisted system libs, so, this is basically overkill ;).
if depth > 0 and (pspec == "/system/lib" or library == "libdl.so") then
-- depth > 0 to allow explicitly loading a system lib
-- (because this might have genuine use cases, as some early API levels do not put DT_NEEDED libraries into the global namespace)
-- pspec to reject system libs
-- secondary check on libdl, because apparently there are old ROMs out there where it isn't in /sytem/lib ?!
A.LOGVV(log, string.format("%"..padding.."sdl.dlopen - skipping %s (system lib)", "", lname))
-- We won't load it, so, we don't even need to look at its deps.
lib:close()
return nil
end

depth = depth + 1
padding = depth * 4
-- we found a library, now load its requirements
-- we do _not_ pass the load_func to the cascaded
-- calls, so those will always use sys_dlopen()
for _, needed in pairs(lib:dlneeds()) do
if needed == "libluajit.so" then
--[[
-- load the luajit-launcher libluajit with sys_dlopen
load_func("libluajit.so")
--]]
-- Do *NOT* load libluajit if it's needed by something: we're already linked against a static copy!
A.LOGVV(log, string.format(" dl.dlopen - skipping needed %s for %s", needed, lname))
elseif needed ~= "libdl.so" and pspec ~= "/system/lib" then
-- For Android >= 6.0, the list of safe system libraries is:
-- libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics,
-- liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++,
-- libvulkan, and libz
-- However, we have our own dl implementation and don't need the rest.
A.LOGVV(log, string.format(" dl.dlopen - opening needed %s for %s", needed, lname))
dl.dlopen(needed)
end
local lib_needs = lib:dlneeds()
lib:close()
for i, needed in ipairs(lib_needs) do
A.LOGVV(log, string.format("%"..padding.."sdl.dlopen - needed => %s (%d of %d) <= %s", "", needed, i, #lib_needs, lname))
dl.dlopen(needed, sys_dlopen, depth)
end
depth = depth - 1
padding = depth * 4
if load_func == sys_dlopen then
return sys_dlopen(lname, false, padding)
else
A.LOGVV(log, string.format("%"..padding.."sdl.dlopen - load_func -> %s", "", lname))
return load_func(lname)
end
return load_func(lname)
end
end

Expand Down
Loading