libdl: platform headers
Defining headers provides the most type safety.
Previously, libdl exposed APIs via extern. However, this is
errorprone. We have much better tools in the Android build
to guard API usage. Specifically, apps, mainline modules,
vendor code, and other unbundled code paths would avoid
using these headers.
Moving function to header as requested by NDK API Council
for new methods.
Future steps that would make sense would be cleaning up
dlext_private_tests and combining it here, and also
removing other 'extern' uses of libdl symbols.
Bug: 382285049
Test: links
Change-Id: I23eb1d8a2c3a81e4f2892a726c46be89f2c992fa
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 87db4b1..205c454 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -60,6 +60,8 @@
native_bridge_supported: true,
static_ndk_lib: true,
+ export_include_dirs: ["include_private"],
+
defaults: [
"linux_bionic_supported",
"bug_24465209_workaround",
diff --git a/libdl/include_private/android/dlext_private.h b/libdl/include_private/android/dlext_private.h
new file mode 100644
index 0000000..fda1086
--- /dev/null
+++ b/libdl/include_private/android/dlext_private.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// TODO: libdl has several private extensions, but they have not all moved into a standard
+// private header.
+
+/**
+ * Set whether to load libraries in app compat mode.
+ *
+ * Any library which is not 16 KB aligned on a 4 KB aligned
+ * will be loaded in a special mode, which may load some R-only
+ * code as RW, in order to increase compatibility.
+ *
+ * \param enable_app_compat whether the mode is enabled for additional
+ * library loads.
+ */
+void android_set_16kb_appcompat_mode(bool enable_app_compat);
+
+__END_DECLS
diff --git a/tests/dlext_private.h b/tests/dlext_private_tests.h
similarity index 100%
rename from tests/dlext_private.h
rename to tests/dlext_private_tests.h
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 8b26cb0..b8826c1 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -44,7 +44,7 @@
#include "bionic/mte.h"
#include "bionic/page.h"
#include "core_shared_libs.h"
-#include "dlext_private.h"
+#include "dlext_private_tests.h"
#include "dlfcn_symlink_support.h"
#include "gtest_globals.h"
#include "utils.h"
diff --git a/tests/libs/ns_hidden_child_helper.cpp b/tests/libs/ns_hidden_child_helper.cpp
index c2140f1..77608e2 100644
--- a/tests/libs/ns_hidden_child_helper.cpp
+++ b/tests/libs/ns_hidden_child_helper.cpp
@@ -33,7 +33,7 @@
#include <string>
#include "../core_shared_libs.h"
-#include "../dlext_private.h"
+#include "../dlext_private_tests.h"
extern "C" void global_function();
extern "C" void internal_function();
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 3f1ba79..2ce789e 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -53,7 +53,7 @@
#if defined(__BIONIC__)
#include "SignalUtils.h"
-#include "dlext_private.h"
+#include "dlext_private_tests.h"
#include "platform/bionic/malloc.h"
#include "platform/bionic/mte.h"
diff --git a/tests/page_size_16kib_compat_test.cpp b/tests/page_size_16kib_compat_test.cpp
index a5d91b8..cfd52e2 100644
--- a/tests/page_size_16kib_compat_test.cpp
+++ b/tests/page_size_16kib_compat_test.cpp
@@ -26,11 +26,17 @@
* SUCH DAMAGE.
*/
+#if __has_include (<android/dlext_private.h>)
+#define IS_ANDROID_DL
+#endif
+
#include "page_size_compat_helpers.h"
#include <android-base/properties.h>
-extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
+#if defined(IS_ANDROID_DL)
+#include <android/dlext_private.h>
+#endif
TEST(PageSize16KiBCompatTest, ElfAlignment4KiB_LoadElf) {
if (getpagesize() != 0x4000) {
@@ -52,11 +58,17 @@
GTEST_SKIP() << "This test is only applicable to 16kB page-size devices";
}
+#if defined(IS_ANDROID_DL)
android_set_16kb_appcompat_mode(true);
+#endif
+
std::string lib = GetTestLibRoot() + "/libtest_elf_max_page_size_4kib.so";
void* handle = nullptr;
OpenTestLibrary(lib, false /*should_fail*/, &handle);
CallTestFunction(handle);
+
+#if defined(IS_ANDROID_DL)
android_set_16kb_appcompat_mode(false);
+#endif
}