[-]
[+]
|
Changed |
_service:tar_git:libhybris.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris.spec
^
|
|
[-]
[+]
|
Deleted |
_service:tar_git:libhybris-0.0.5.23.tar.bz2/libhybris/hybris/properties/properties.c
^
|
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
- * 2008 The Android Open Source Project
- * 2013 Simon Busch <morphis@gravedo.de>
- * 2013 Canonical Ltd
- *
- * 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.
- *
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#define __USE_GNU
-#include <unistd.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <poll.h>
-
-#include <hybris/properties/properties.h>
-#include "properties_p.h"
-
-
-static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
-static int send_prop_msg_no_reply = 0;
-
-/* Get/Set a property from the Android Init property socket */
-static int send_prop_msg(prop_msg_t *msg,
- void (*propfn)(const char *, const char *, void *),
- void *cookie)
-{
- union {
- struct sockaddr_un addr;
- struct sockaddr addr_g;
- } addr;
- socklen_t alen;
- size_t namelen;
- int s;
- int r;
- int result = -1;
- int patched_init = 0;
-
- /* if we tried to talk to the server in the past and didn't get a reply,
- * it's fairly safe to say that init is not patched and this is all
- * hopeless, so we should just quit while we're ahead
- */
- if (send_prop_msg_no_reply == 1)
- return -EIO;
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- return result;
- }
-
- memset(&addr, 0, sizeof(addr));
- namelen = strlen(property_service_socket);
- strncpy(addr.addr.sun_path, property_service_socket,
- sizeof(addr.addr.sun_path));
- addr.addr.sun_family = AF_LOCAL;
- alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
-
- if (TEMP_FAILURE_RETRY(connect(s, &addr.addr_g, alen) < 0)) {
- close(s);
- return result;
- }
-
- r = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg_t), 0));
-
- if (r == sizeof(prop_msg_t)) {
- // We successfully wrote to the property server, so use recv
- // in case we need to get a property. Once the other side is
- // finished, the socket is closed.
- while ((r = recv(s, msg, sizeof(prop_msg_t), 0)) > 0) {
- if (r != sizeof(prop_msg_t)) {
- close(s);
- return result;
- }
-
- /* If we got a reply, this is a patched init */
- if (!patched_init)
- patched_init = 1;
-
- if (propfn)
- propfn(msg->name, msg->value, cookie);
- }
-
- /* We also just get a close in case of setprop */
- if ((r >= 0) && (patched_init ||
- (msg->cmd == PROP_MSG_SETPROP))) {
- result = 0;
- } else {
- send_prop_msg_no_reply = 1;
- }
- }
-
- close(s);
- return result;
-}
-
-int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie)
-{
- int err;
- prop_msg_t msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.cmd = PROP_MSG_LISTPROP;
-
- err = send_prop_msg(&msg, propfn, cookie);
- if (err < 0)
- /* fallback to property cache */
- hybris_propcache_list((hybris_propcache_list_cb) propfn, cookie);
-
- return 0;
-}
-
-static int property_get_socket(const char *key, char *value, const char *default_value)
-{
- int err;
- prop_msg_t msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.cmd = PROP_MSG_GETPROP;
-
- if (key) {
- strncpy(msg.name, key, sizeof(msg.name));
- err = send_prop_msg(&msg, NULL, NULL);
- if (err < 0)
- return err;
- }
-
- /* In case it's null, just use the default */
- if ((strlen(msg.value) == 0) && (default_value)) {
- if (strlen(default_value) > PROP_VALUE_MAX -1) return -1;
- strcpy(msg.value, default_value);
- }
-
- strcpy(value, msg.value);
-
- return 0;
-}
-
-int property_get(const char *key, char *value, const char *default_value)
-{
- char *ret = NULL;
-
- if ((key) && (strlen(key) > PROP_NAME_MAX -1)) return -1;
- if (value == NULL) return -1;
-
-
- // Runtime cache will serialize property lookups within the process.
- // This will increase latency if multiple threads are doing many
- // parallel lookups to new properties, but the overhead should
- // be offset with the caching eventually.
- runtime_cache_lock();
- if (runtime_cache_get(key, value) == 0) {
- ret = value;
- } else if (property_get_socket(key, value, default_value) == 0) {
- runtime_cache_insert(key, value);
- ret = value;
- }
- runtime_cache_unlock();
-
- if (ret)
- return strlen(ret);
-
-
- /* In case the socket is not available, search the property file cache by hand */
- ret = hybris_propcache_find(key);
-
- if (ret) {
- strcpy(value, ret);
- return strlen(value);
- } else if (default_value != NULL) {
- strcpy(value, default_value);
- return strlen(value);
- } else {
- value = '\0';
- }
-
- return 0;
-}
-
-int property_set(const char *key, const char *value)
-{
- int err;
- prop_msg_t msg;
-
- if (key == 0) return -1;
- if (value == 0) value = "";
- if (strlen(key) > PROP_NAME_MAX -1) return -1;
- if (strlen(value) > PROP_VALUE_MAX -1) return -1;
-
- runtime_cache_lock();
- runtime_cache_remove(key);
- runtime_cache_unlock();
-
- memset(&msg, 0, sizeof(msg));
- msg.cmd = PROP_MSG_SETPROP;
- strncpy(msg.name, key, sizeof(msg.name));
- strncpy(msg.value, value, sizeof(msg.value));
-
- err = send_prop_msg(&msg, NULL, NULL);
- if (err < 0) {
- return err;
- }
-
- return 0;
-}
-
-// vim:ts=4:sw=4:noexpandtab
|
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/.gitmodules
^
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/camera/Android.mk
^
|
@@ -1,4 +1,11 @@
LOCAL_PATH:= $(call my-dir)
+
+HYBRIS_MEDIA_32_BIT_ONLY := $(shell cat frameworks/av/media/libmediaplayerservice/Android.mk |grep LOCAL_32_BIT_ONLY |grep -o "true\|false")
+
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+HYBRIS_MEDIA_MULTILIB := 32
+endif
+
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../Android.common.mk
@@ -21,6 +28,11 @@
libui \
libgui
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := 32
+endif
+
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
@@ -40,9 +52,8 @@
LOCAL_C_INCLUDES := \
$(HYBRIS_PATH)/include \
bionic \
- bionic/libstdc++/include \
+ external/libcxx/include \
external/gtest/include \
- external/stlport/stlport \
external/skia/include/core \
LOCAL_SHARED_LIBRARIES := \
@@ -60,4 +71,9 @@
libEGL \
libGLESv2
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := 32
+endif
+
include $(BUILD_EXECUTABLE)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/camera/camera_compatibility_layer.cpp
^
|
@@ -50,8 +50,9 @@
#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <utils/String16.h>
-
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
#include <gui/NativeBufferAlloc.h>
+#endif
#include <cstring>
@@ -140,6 +141,12 @@
(void) data;
}
+void CameraControl::postRecordingFrameHandleTimestamp(nsecs_t /*timestamp*/, native_handle_t* /*handle*/)
+{
+ REPORT_FUNCTION();
+}
+
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
namespace android
{
NativeBufferAlloc::NativeBufferAlloc() {
@@ -165,6 +172,7 @@
return graphicBuffer;
}
}
+#endif
int android_camera_get_number_of_devices()
{
@@ -220,7 +228,9 @@
android::sp<CameraControl> cc = new CameraControl();
cc->listener = listener;
-#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR==5 || ANDROID_VERSION_MAJOR>=6
+#if ANDROID_VERSION_MAJOR>=7
+ cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID, android::Camera::USE_CALLING_PID);
+#elif ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR>=3 || ANDROID_VERSION_MAJOR>=5
cc->camera = android::Camera::connect(camera_id, android::String16("hybris"), android::Camera::USE_CALLING_UID);
#else
cc->camera = android::Camera::connect(camera_id);
@@ -315,10 +325,13 @@
assert(control);
android::Mutex::Autolock al(control->guard);
- android::String8 raw_modes;
- raw_modes = android::String8(
+ const char* raw_modes_cstr =
control->camera_parameters.get(
- android::CameraParameters::KEY_SUPPORTED_FLASH_MODES));
+ android::CameraParameters::KEY_SUPPORTED_FLASH_MODES);
+ if (!raw_modes_cstr)
+ return;
+
+ android::String8 raw_modes = android::String8(raw_modes_cstr);
const char delimiter[2] = ",";
char *token;
@@ -685,9 +698,11 @@
static const bool allow_synchronous_mode = false;
static const bool is_controlled_by_app = true;
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
android::sp<android::NativeBufferAlloc> native_alloc(
new android::NativeBufferAlloc()
);
+#endif
#if ANDROID_VERSION_MAJOR>=5
android::sp<android::IGraphicBufferProducer> producer;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/camera/direct_camera_test.cpp
^
|
@@ -675,6 +675,7 @@
while (1) {
usleep(50);
+ preview_texture_needs_update_cb(0);
}
stop_video_recording(recorder);
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/Android.mk
^
|
@@ -0,0 +1,120 @@
+# define ANDROID_VERSION MAJOR, MINOR and PATCH
+
+ANDROID_VERSION_MAJOR := $(word 1, $(subst ., , $(PLATFORM_VERSION)))
+ANDROID_VERSION_MINOR := $(word 2, $(subst ., , $(PLATFORM_VERSION)))
+ANDROID_VERSION_PATCH := $(word 3, $(subst ., , $(PLATFORM_VERSION)))
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhwc2_compat_layer
+LOCAL_SRC_FILES := HWC2.cpp ComposerHal.cpp hwc2_compatibility_layer.cpp
+
+LOCAL_C_INCLUDES := ../hybris/include
+
+ifeq ($(strip $(ANDROID_VERSION_MAJOR)),9)
+LOCAL_C_INCLUDES += \
+ hardware/interfaces/graphics/composer/2.1/utils/command-buffer/include
+LOCAL_HEADER_LIBRARIES : \
+ android.hardware.graphics.composer@2.1-command-buffer
+else
+LOCAL_STATIC_LIBRARIES := \
+ libhwcomposer-command-buffer
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+ android.frameworks.vr.composer@1.0 \
+ android.hardware.graphics.allocator@2.0 \
+ android.hardware.graphics.composer@2.1 \
+ android.hardware.configstore@1.0 \
+ android.hardware.configstore-utils \
+ libcutils \
+ liblog \
+ libfmq \
+ libhardware \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ libEGL \
+ libGLESv1_CM \
+ libGLESv2 \
+ libbinder \
+ libui \
+ libgui \
+ libsync \
+ libbase
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ android.hardware.graphics.allocator@2.0 \
+ android.hardware.graphics.composer@2.1 \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder
+
+LOCAL_CFLAGS += -Wno-unused-parameter -DGL_GLEXT_PROTOTYPES -UNDEBUG
+LOCAL_CFLAGS += \
+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhybris-gralloc
+LOCAL_SRC_FILES := tests/hybris-gralloc.c \
+ GrallocUsageConversion.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/tests
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_CFLAGS := \
+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH) \
+ -DANDROID_BUILD=1
+LOCAL_CFLAGS += -Wno-unused-parameter -UNDEBUG -DHAS_GRALLOC1_HEADER=1
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhwcnativewindow
+LOCAL_SRC_FILES := tests/hwcomposer_window.cpp \
+ tests/nativewindowbase.cpp
+LOCAL_SHARED_LIBRARIES := libsync liblog libnativewindow
+LOCAL_CFLAGS := \
+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH) \
+ -DANDROID_BUILD=1
+LOCAL_CFLAGS += -Wno-unused-parameter -UNDEBUG
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := direct_hwc2_test
+LOCAL_SRC_FILES := tests/direct_hwc2_test.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/tests
+ifdef TARGET_2ND_ARCH
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(if $(filter false,$(BOARD_UBUNTU_PREFER_32_BIT)),$(LOCAL_MODULE)$(TARGET_2ND_ARCH_MODULE_SUFFIX),$(LOCAL_MODULE))
+LOCAL_MODULE_STEM_64 := $(if $(filter false,$(BOARD_UBUNTU_PREFER_32_BIT)),$(LOCAL_MODULE),$(LOCAL_MODULE)_64)
+endif
+
+LOCAL_STATIC_LIBRARIES := \
+ libhwcnativewindow libhybris-gralloc
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ liblog \
+ libhardware \
+ libnativewindow \
+ libsync \
+ libEGL \
+ libGLESv2 \
+ libhwc2_compat_layer
+
+LOCAL_CFLAGS += -Wno-unused-parameter -DGL_GLEXT_PROTOTYPES -UNDEBUG \
+ -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION
+LOCAL_CFLAGS += \
+ -DANDROID_VERSION_MAJOR=$(ANDROID_VERSION_MAJOR) \
+ -DANDROID_VERSION_MINOR=$(ANDROID_VERSION_MINOR) \
+ -DANDROID_VERSION_PATCH=$(ANDROID_VERSION_PATCH)
+
+include $(BUILD_EXECUTABLE)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/ComposerHal.cpp
^
|
@@ -0,0 +1,1118 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "HwcComposer"
+
+#include <inttypes.h>
+#include <log/log.h>
+#include <gui/BufferQueue.h>
+
+#include "ComposerHal.h"
+
+namespace android {
+
+using hardware::Return;
+using hardware::hidl_vec;
+using hardware::hidl_handle;
+
+namespace Hwc2 {
+
+namespace {
+
+class BufferHandle {
+public:
+ BufferHandle(const native_handle_t* buffer)
+ {
+ // nullptr is not a valid handle to HIDL
+ mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
+ }
+
+ operator const hidl_handle&() const
+ {
+ return mHandle;
+ }
+
+private:
+ NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
+ hidl_handle mHandle;
+};
+
+class FenceHandle
+{
+public:
+ FenceHandle(int fd, bool owned)
+ : mOwned(owned)
+ {
+ native_handle_t* handle;
+ if (fd >= 0) {
+ handle = native_handle_init(mStorage, 1, 0);
+ handle->data[0] = fd;
+ } else {
+ // nullptr is not a valid handle to HIDL
+ handle = native_handle_init(mStorage, 0, 0);
+ }
+ mHandle = handle;
+ }
+
+ ~FenceHandle()
+ {
+ if (mOwned) {
+ native_handle_close(mHandle);
+ }
+ }
+
+ operator const hidl_handle&() const
+ {
+ return mHandle;
+ }
+
+private:
+ bool mOwned;
+ NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
+ hidl_handle mHandle;
+};
+
+// assume NO_RESOURCES when Status::isOk returns false
+constexpr Error kDefaultError = Error::NO_RESOURCES;
+
+template<typename T, typename U>
+T unwrapRet(Return<T>& ret, const U& default_val)
+{
+ return (ret.isOk()) ? static_cast<T>(ret) :
+ static_cast<T>(default_val);
+}
+
+Error unwrapRet(Return<Error>& ret)
+{
+ return unwrapRet(ret, kDefaultError);
+}
+
+} // anonymous namespace
+
+Composer::CommandWriter::CommandWriter(uint32_t initialMaxSize)
+ : CommandWriterBase(initialMaxSize) {}
+
+Composer::CommandWriter::~CommandWriter()
+{
+}
+
+void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
+{
+ constexpr uint16_t kSetLayerInfoLength = 2;
+ beginCommand(
+ static_cast<IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_INFO),
+ kSetLayerInfoLength);
+ write(type);
+ write(appId);
+ endCommand();
+}
+
+void Composer::CommandWriter::setClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ constexpr uint16_t kSetClientTargetMetadataLength = 7;
+ beginCommand(
+ static_cast<IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
+ kSetClientTargetMetadataLength);
+ writeBufferMetadata(metadata);
+ endCommand();
+}
+
+void Composer::CommandWriter::setLayerBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ constexpr uint16_t kSetLayerBufferMetadataLength = 7;
+ beginCommand(
+ static_cast<IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
+ kSetLayerBufferMetadataLength);
+ writeBufferMetadata(metadata);
+ endCommand();
+}
+
+void Composer::CommandWriter::writeBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ write(metadata.width);
+ write(metadata.height);
+ write(metadata.stride);
+ write(metadata.layerCount);
+ writeSigned(static_cast<int32_t>(metadata.format));
+ write64(metadata.usage);
+}
+
+Composer::Composer(bool useVrComposer)
+ : mWriter(kWriterInitialSize),
+ mIsUsingVrComposer(useVrComposer)
+{
+ if (mIsUsingVrComposer) {
+ mComposer = IComposer::getService("vr");
+ } else {
+ mComposer = IComposer::getService(); // use default name
+ }
+
+ if (mComposer == nullptr) {
+ LOG_ALWAYS_FATAL("failed to get hwcomposer service");
+ }
+
+ mComposer->createClient(
+ [&](const auto& tmpError, const auto& tmpClient)
+ {
+ if (tmpError == Error::NONE) {
+ mClient = tmpClient;
+ }
+ });
+ if (mClient == nullptr) {
+ LOG_ALWAYS_FATAL("failed to create composer client");
+ }
+
+ if (mIsUsingVrComposer) {
+ sp<IVrComposerClient> vrClient = IVrComposerClient::castFrom(mClient);
+ if (vrClient == nullptr) {
+ LOG_ALWAYS_FATAL("failed to create vr composer client");
+ }
+ }
+}
+
+std::vector<IComposer::Capability> Composer::getCapabilities()
+{
+ std::vector<IComposer::Capability> capabilities;
+ mComposer->getCapabilities(
+ [&](const auto& tmpCapabilities) {
+ capabilities = tmpCapabilities;
+ });
+
+ return capabilities;
+}
+
+std::string Composer::dumpDebugInfo()
+{
+ std::string info;
+ mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
+ info = tmpInfo.c_str();
+ });
+
+ return info;
+}
+
+void Composer::registerCallback(const sp<IComposerCallback>& callback)
+{
+ auto ret = mClient->registerCallback(callback);
+ if (!ret.isOk()) {
+ ALOGE("failed to register IComposerCallback");
+ }
+}
+
+bool Composer::isRemote() {
+ return mClient->isRemote();
+}
+
+void Composer::resetCommands() {
+ mWriter.reset();
+}
+
+uint32_t Composer::getMaxVirtualDisplayCount()
+{
+ auto ret = mClient->getMaxVirtualDisplayCount();
+ return unwrapRet(ret, 0);
+}
+
+Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay)
+{
+ const uint32_t bufferSlotCount = 1;
+ Error error = kDefaultError;
+ mClient->createVirtualDisplay(width, height, *format, bufferSlotCount,
+ [&](const auto& tmpError, const auto& tmpDisplay,
+ const auto& tmpFormat) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outDisplay = tmpDisplay;
+ *format = tmpFormat;
+ });
+
+ return error;
+}
+
+Error Composer::destroyVirtualDisplay(Display display)
+{
+ auto ret = mClient->destroyVirtualDisplay(display);
+ return unwrapRet(ret);
+}
+
+Error Composer::acceptDisplayChanges(Display display)
+{
+ mWriter.selectDisplay(display);
+ mWriter.acceptDisplayChanges();
+ return Error::NONE;
+}
+
+Error Composer::createLayer(Display display, Layer* outLayer)
+{
+ Error error = kDefaultError;
+ mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
+ [&](const auto& tmpError, const auto& tmpLayer) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outLayer = tmpLayer;
+ });
+
+ return error;
+}
+
+Error Composer::destroyLayer(Display display, Layer layer)
+{
+ auto ret = mClient->destroyLayer(display, layer);
+ return unwrapRet(ret);
+}
+
+Error Composer::getActiveConfig(Display display, Config* outConfig)
+{
+ Error error = kDefaultError;
+ mClient->getActiveConfig(display,
+ [&](const auto& tmpError, const auto& tmpConfig) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outConfig = tmpConfig;
+ });
+
+ return error;
+}
+
+Error Composer::getChangedCompositionTypes(Display display,
+ std::vector<Layer>* outLayers,
+ std::vector<IComposerClient::Composition>* outTypes)
+{
+ mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
+ return Error::NONE;
+}
+
+Error Composer::getColorModes(Display display,
+ std::vector<ColorMode>* outModes)
+{
+ Error error = kDefaultError;
+ mClient->getColorModes(display,
+ [&](const auto& tmpError, const auto& tmpModes) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outModes = tmpModes;
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue)
+{
+ Error error = kDefaultError;
+ mClient->getDisplayAttribute(display, config, attribute,
+ [&](const auto& tmpError, const auto& tmpValue) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outValue = tmpValue;
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayConfigs(Display display,
+ std::vector<Config>* outConfigs)
+{
+ Error error = kDefaultError;
+ mClient->getDisplayConfigs(display,
+ [&](const auto& tmpError, const auto& tmpConfigs) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outConfigs = tmpConfigs;
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayName(Display display, std::string* outName)
+{
+ Error error = kDefaultError;
+ mClient->getDisplayName(display,
+ [&](const auto& tmpError, const auto& tmpName) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outName = tmpName.c_str();
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayRequests(Display display,
+ uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
+ std::vector<uint32_t>* outLayerRequestMasks)
+{
+ mReader.takeDisplayRequests(display, outDisplayRequestMask,
+ outLayers, outLayerRequestMasks);
+ return Error::NONE;
+}
+
+Error Composer::getDisplayType(Display display,
+ IComposerClient::DisplayType* outType)
+{
+ Error error = kDefaultError;
+ mClient->getDisplayType(display,
+ [&](const auto& tmpError, const auto& tmpType) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outType = tmpType;
+ });
+
+ return error;
+}
+
+Error Composer::getDozeSupport(Display display, bool* outSupport)
+{
+ Error error = kDefaultError;
+ mClient->getDozeSupport(display,
+ [&](const auto& tmpError, const auto& tmpSupport) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outSupport = tmpSupport;
+ });
+
+ return error;
+}
+
+Error Composer::getHdrCapabilities(Display display,
+ std::vector<Hdr>* outTypes, float* outMaxLuminance,
+ float* outMaxAverageLuminance, float* outMinLuminance)
+{
+ Error error = kDefaultError;
+ mClient->getHdrCapabilities(display,
+ [&](const auto& tmpError, const auto& tmpTypes,
+ const auto& tmpMaxLuminance,
+ const auto& tmpMaxAverageLuminance,
+ const auto& tmpMinLuminance) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outTypes = tmpTypes;
+ *outMaxLuminance = tmpMaxLuminance;
+ *outMaxAverageLuminance = tmpMaxAverageLuminance;
+ *outMinLuminance = tmpMinLuminance;
+ });
+
+ return error;
+}
+
+Error Composer::getReleaseFences(Display display,
+ std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
+{
+ mReader.takeReleaseFences(display, outLayers, outReleaseFences);
+ return Error::NONE;
+}
+
+Error Composer::presentDisplay(Display display, int* outPresentFence)
+{
+ mWriter.selectDisplay(display);
+ mWriter.presentDisplay();
+
+ Error error = execute();
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ mReader.takePresentFence(display, outPresentFence);
+
+ return Error::NONE;
+}
+
+Error Composer::setActiveConfig(Display display, Config config)
+{
+ auto ret = mClient->setActiveConfig(display, config);
+ return unwrapRet(ret);
+}
+
+Error Composer::setClientTarget(Display display, uint32_t slot,
+ const sp<GraphicBuffer>& target,
+ int acquireFence, Dataspace dataspace,
+ const std::vector<IComposerClient::Rect>& damage)
+{
+ mWriter.selectDisplay(display);
+ if (mIsUsingVrComposer && target.get()) {
+ IVrComposerClient::BufferMetadata metadata = {
+ .width = target->getWidth(),
+ .height = target->getHeight(),
+ .stride = target->getStride(),
+ .layerCount = target->getLayerCount(),
+ .format = static_cast<PixelFormat>(target->getPixelFormat()),
+ .usage = target->getUsage(),
+ };
+ mWriter.setClientTargetMetadata(metadata);
+ }
+
+ const native_handle_t* handle = nullptr;
+ if (target.get()) {
+ handle = target->getNativeBuffer()->handle;
+ }
+
+ mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
+ return Error::NONE;
+}
+
+Error Composer::setColorMode(Display display, ColorMode mode)
+{
+ auto ret = mClient->setColorMode(display, mode);
+ return unwrapRet(ret);
+}
+
+Error Composer::setColorTransform(Display display, const float* matrix,
+ ColorTransform hint)
+{
+ mWriter.selectDisplay(display);
+ mWriter.setColorTransform(matrix, hint);
+ return Error::NONE;
+}
+
+Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
+ int releaseFence)
+{
+ mWriter.selectDisplay(display);
+ mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
+ return Error::NONE;
+}
+
+Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
+{
+ auto ret = mClient->setPowerMode(display, mode);
+ return unwrapRet(ret);
+}
+
+Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
+{
+ auto ret = mClient->setVsyncEnabled(display, enabled);
+ return unwrapRet(ret);
+}
+
+Error Composer::setClientTargetSlotCount(Display display)
+{
+ const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
+ auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
+ return unwrapRet(ret);
+}
+
+Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
+ uint32_t* outNumRequests)
+{
+ mWriter.selectDisplay(display);
+ mWriter.validateDisplay();
+
+ Error error = execute();
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ mReader.hasChanges(display, outNumTypes, outNumRequests);
+
+ return Error::NONE;
+}
+
+Error Composer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
+ uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) {
+ mWriter.selectDisplay(display);
+ mWriter.presentOrvalidateDisplay();
+
+ Error error = execute();
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ mReader.takePresentOrValidateStage(display, state);
+
+ if (*state == 1) { // Present succeeded
+ mReader.takePresentFence(display, outPresentFence);
+ }
+
+ if (*state == 0) { // Validate succeeded.
+ mReader.hasChanges(display, outNumTypes, outNumRequests);
+ }
+
+ return Error::NONE;
+}
+
+Error Composer::setCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerCursorPosition(x, y);
+ return Error::NONE;
+}
+
+Error Composer::setLayerBuffer(Display display, Layer layer,
+ uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ if (mIsUsingVrComposer && buffer.get()) {
+ IVrComposerClient::BufferMetadata metadata = {
+ .width = buffer->getWidth(),
+ .height = buffer->getHeight(),
+ .stride = buffer->getStride(),
+ .layerCount = buffer->getLayerCount(),
+ .format = static_cast<PixelFormat>(buffer->getPixelFormat()),
+ .usage = buffer->getUsage(),
+ };
+ mWriter.setLayerBufferMetadata(metadata);
+ }
+
+ const native_handle_t* handle = nullptr;
+ if (buffer.get()) {
+ handle = buffer->getNativeBuffer()->handle;
+ }
+
+ mWriter.setLayerBuffer(slot, handle, acquireFence);
+ return Error::NONE;
+}
+
+Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& damage)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerSurfaceDamage(damage);
+ return Error::NONE;
+}
+
+Error Composer::setLayerBlendMode(Display display, Layer layer,
+ IComposerClient::BlendMode mode)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerBlendMode(mode);
+ return Error::NONE;
+}
+
+Error Composer::setLayerColor(Display display, Layer layer,
+ const IComposerClient::Color& color)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerColor(color);
+ return Error::NONE;
+}
+
+Error Composer::setLayerCompositionType(Display display, Layer layer,
+ IComposerClient::Composition type)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerCompositionType(type);
+ return Error::NONE;
+}
+
+Error Composer::setLayerDataspace(Display display, Layer layer,
+ Dataspace dataspace)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerDataspace(dataspace);
+ return Error::NONE;
+}
+
+Error Composer::setLayerDisplayFrame(Display display, Layer layer,
+ const IComposerClient::Rect& frame)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerDisplayFrame(frame);
+ return Error::NONE;
+}
+
+Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerPlaneAlpha(alpha);
+ return Error::NONE;
+}
+
+Error Composer::setLayerSidebandStream(Display display, Layer layer,
+ const native_handle_t* stream)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerSidebandStream(stream);
+ return Error::NONE;
+}
+
+Error Composer::setLayerSourceCrop(Display display, Layer layer,
+ const IComposerClient::FRect& crop)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerSourceCrop(crop);
+ return Error::NONE;
+}
+
+Error Composer::setLayerTransform(Display display, Layer layer,
+ Transform transform)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerTransform(transform);
+ return Error::NONE;
+}
+
+Error Composer::setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& visible)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerVisibleRegion(visible);
+ return Error::NONE;
+}
+
+Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
+{
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerZOrder(z);
+ return Error::NONE;
+}
+
+Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
+ uint32_t appId)
+{
+ if (mIsUsingVrComposer) {
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+ mWriter.setLayerInfo(type, appId);
+ }
+ return Error::NONE;
+}
+
+Error Composer::execute()
+{
+ // prepare input command queue
+ bool queueChanged = false;
+ uint32_t commandLength = 0;
+ hidl_vec<hidl_handle> commandHandles;
+ if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
+ mWriter.reset();
+ return Error::NO_RESOURCES;
+ }
+
+ // set up new input command queue if necessary
+ if (queueChanged) {
+ auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
+ auto error = unwrapRet(ret);
+ if (error != Error::NONE) {
+ mWriter.reset();
+ return error;
+ }
+ }
+
+ Error error = kDefaultError;
+ auto ret = mClient->executeCommands(commandLength, commandHandles,
+ [&](const auto& tmpError, const auto& tmpOutChanged,
+ const auto& tmpOutLength, const auto& tmpOutHandles)
+ {
+ error = tmpError;
+
+ // set up new output command queue if necessary
+ if (error == Error::NONE && tmpOutChanged) {
+ error = kDefaultError;
+ mClient->getOutputCommandQueue(
+ [&](const auto& tmpError,
+ const auto& tmpDescriptor)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ mReader.setMQDescriptor(tmpDescriptor);
+ });
+ }
+
+ if (error != Error::NONE) {
+ return;
+ }
+
+ if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
+ error = mReader.parse();
+ mReader.reset();
+ } else {
+ error = Error::NO_RESOURCES;
+ }
+ });
+ // executeCommands can fail because of out-of-fd and we do not want to
+ // abort() in that case
+ if (!ret.isOk()) {
+ ALOGE("executeCommands failed because of %s", ret.description().c_str());
+ }
+
+ if (error == Error::NONE) {
+ std::vector<CommandReader::CommandError> commandErrors =
+ mReader.takeErrors();
+
+ for (const auto& cmdErr : commandErrors) {
+ auto command = mWriter.getCommand(cmdErr.location);
+
+ if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
+ command == IComposerClient::Command::PRESENT_DISPLAY ||
+ command == IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY) {
+ error = cmdErr.error;
+ } else {
+ ALOGW("command 0x%x generated error %d",
+ command, cmdErr.error);
+ }
+ }
+ }
+
+ mWriter.reset();
+
+ return error;
+}
+
+CommandReader::~CommandReader()
+{
+ resetData();
+}
+
+Error CommandReader::parse()
+{
+ resetData();
+
+ IComposerClient::Command command;
+ uint16_t length = 0;
+
+ while (!isEmpty()) {
+ if (!beginCommand(&command, &length)) {
+ break;
+ }
+
+ bool parsed = false;
+ switch (command) {
+ case IComposerClient::Command::SELECT_DISPLAY:
+ parsed = parseSelectDisplay(length);
+ break;
+ case IComposerClient::Command::SET_ERROR:
+ parsed = parseSetError(length);
+ break;
+ case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
+ parsed = parseSetChangedCompositionTypes(length);
+ break;
+ case IComposerClient::Command::SET_DISPLAY_REQUESTS:
+ parsed = parseSetDisplayRequests(length);
+ break;
+ case IComposerClient::Command::SET_PRESENT_FENCE:
+ parsed = parseSetPresentFence(length);
+ break;
+ case IComposerClient::Command::SET_RELEASE_FENCES:
+ parsed = parseSetReleaseFences(length);
+ break;
+ case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
+ parsed = parseSetPresentOrValidateDisplayResult(length);
+ break;
+ default:
+ parsed = false;
+ break;
+ }
+
+ endCommand();
+
+ if (!parsed) {
+ ALOGE("failed to parse command 0x%x length %" PRIu16,
+ command, length);
+ break;
+ }
+ }
+
+ return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
+}
+
+bool CommandReader::parseSelectDisplay(uint16_t length)
+{
+ if (length != CommandWriterBase::kSelectDisplayLength) {
+ return false;
+ }
+
+ mCurrentReturnData = &mReturnData[read64()];
+
+ return true;
+}
+
+bool CommandReader::parseSetError(uint16_t length)
+{
+ if (length != CommandWriterBase::kSetErrorLength) {
+ return false;
+ }
+
+ auto location = read();
+ auto error = static_cast<Error>(readSigned());
+
+ mErrors.emplace_back(CommandError{location, error});
+
+ return true;
+}
+
+bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
+{
+ // (layer id, composition type) pairs
+ if (length % 3 != 0 || !mCurrentReturnData) {
+ return false;
+ }
+
+ uint32_t count = length / 3;
+ mCurrentReturnData->changedLayers.reserve(count);
+ mCurrentReturnData->compositionTypes.reserve(count);
+ while (count > 0) {
+ auto layer = read64();
+ auto type = static_cast<IComposerClient::Composition>(readSigned());
+
+ mCurrentReturnData->changedLayers.push_back(layer);
+ mCurrentReturnData->compositionTypes.push_back(type);
+
+ count--;
+ }
+
+ return true;
+}
+
+bool CommandReader::parseSetDisplayRequests(uint16_t length)
+{
+ // display requests followed by (layer id, layer requests) pairs
+ if (length % 3 != 1 || !mCurrentReturnData) {
+ return false;
+ }
+
+ mCurrentReturnData->displayRequests = read();
+
+ uint32_t count = (length - 1) / 3;
+ mCurrentReturnData->requestedLayers.reserve(count);
+ mCurrentReturnData->requestMasks.reserve(count);
+ while (count > 0) {
+ auto layer = read64();
+ auto layerRequestMask = read();
+
+ mCurrentReturnData->requestedLayers.push_back(layer);
+ mCurrentReturnData->requestMasks.push_back(layerRequestMask);
+
+ count--;
+ }
+
+ return true;
+}
+
+bool CommandReader::parseSetPresentFence(uint16_t length)
+{
+ if (length != CommandWriterBase::kSetPresentFenceLength ||
+ !mCurrentReturnData) {
+ return false;
+ }
+
+ if (mCurrentReturnData->presentFence >= 0) {
+ close(mCurrentReturnData->presentFence);
+ }
+ mCurrentReturnData->presentFence = readFence();
+
+ return true;
+}
+
+bool CommandReader::parseSetReleaseFences(uint16_t length)
+{
+ // (layer id, release fence index) pairs
+ if (length % 3 != 0 || !mCurrentReturnData) {
+ return false;
+ }
+
+ uint32_t count = length / 3;
+ mCurrentReturnData->releasedLayers.reserve(count);
+ mCurrentReturnData->releaseFences.reserve(count);
+ while (count > 0) {
+ auto layer = read64();
+ auto fence = readFence();
+
+ mCurrentReturnData->releasedLayers.push_back(layer);
+ mCurrentReturnData->releaseFences.push_back(fence);
+
+ count--;
+ }
+
+ return true;
+}
+
+bool CommandReader::parseSetPresentOrValidateDisplayResult(uint16_t length)
+{
+ if (length != CommandWriterBase::kPresentOrValidateDisplayResultLength || !mCurrentReturnData) {
+ return false;
+ }
+ mCurrentReturnData->presentOrValidateState = read();
+ return true;
+}
+
+void CommandReader::resetData()
+{
+ mErrors.clear();
+
+ for (auto& data : mReturnData) {
+ if (data.second.presentFence >= 0) {
+ close(data.second.presentFence);
+ }
+ for (auto fence : data.second.releaseFences) {
+ if (fence >= 0) {
+ close(fence);
+ }
+ }
+ }
+
+ mReturnData.clear();
+ mCurrentReturnData = nullptr;
+}
+
+std::vector<CommandReader::CommandError> CommandReader::takeErrors()
+{
+ return std::move(mErrors);
+}
+
+bool CommandReader::hasChanges(Display display,
+ uint32_t* outNumChangedCompositionTypes,
+ uint32_t* outNumLayerRequestMasks) const
+{
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outNumChangedCompositionTypes = 0;
+ *outNumLayerRequestMasks = 0;
+ return false;
+ }
+
+ const ReturnData& data = found->second;
+
+ *outNumChangedCompositionTypes = data.compositionTypes.size();
+ *outNumLayerRequestMasks = data.requestMasks.size();
+
+ return !(data.compositionTypes.empty() && data.requestMasks.empty());
+}
+
+void CommandReader::takeChangedCompositionTypes(Display display,
+ std::vector<Layer>* outLayers,
+ std::vector<IComposerClient::Composition>* outTypes)
+{
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ outLayers->clear();
+ outTypes->clear();
+ return;
+ }
+
+ ReturnData& data = found->second;
+
+ *outLayers = std::move(data.changedLayers);
+ *outTypes = std::move(data.compositionTypes);
+}
+
+void CommandReader::takeDisplayRequests(Display display,
+ uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
+ std::vector<uint32_t>* outLayerRequestMasks)
+{
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outDisplayRequestMask = 0;
+ outLayers->clear();
+ outLayerRequestMasks->clear();
+ return;
+ }
+
+ ReturnData& data = found->second;
+
+ *outDisplayRequestMask = data.displayRequests;
+ *outLayers = std::move(data.requestedLayers);
+ *outLayerRequestMasks = std::move(data.requestMasks);
+}
+
+void CommandReader::takeReleaseFences(Display display,
+ std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
+{
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ outLayers->clear();
+ outReleaseFences->clear();
+ return;
+ }
+
+ ReturnData& data = found->second;
+
+ *outLayers = std::move(data.releasedLayers);
+ *outReleaseFences = std::move(data.releaseFences);
+}
+
+void CommandReader::takePresentFence(Display display, int* outPresentFence)
+{
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *outPresentFence = -1;
+ return;
+ }
+
+ ReturnData& data = found->second;
+
+ *outPresentFence = data.presentFence;
+ data.presentFence = -1;
+}
+
+void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) {
+ auto found = mReturnData.find(display);
+ if (found == mReturnData.end()) {
+ *state= -1;
+ return;
+ }
+ ReturnData& data = found->second;
+ *state = data.presentOrValidateState;
+}
+
+} // namespace Hwc2
+
+} // namespace android
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/ComposerHal.h
^
|
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#ifndef ANDROID_SF_COMPOSER_HAL_H
+#define ANDROID_SF_COMPOSER_HAL_H
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <utils/StrongPointer.h>
+#if ANDROID_VERSION_MAJOR >= 9
+#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
+#else
+#include <IComposerCommandBuffer.h>
+#endif
+
+namespace android {
+
+namespace Hwc2 {
+
+using android::frameworks::vr::composer::V1_0::IVrComposerClient;
+
+using android::hardware::graphics::common::V1_0::ColorMode;
+using android::hardware::graphics::common::V1_0::ColorTransform;
+using android::hardware::graphics::common::V1_0::Dataspace;
+using android::hardware::graphics::common::V1_0::Hdr;
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_0::Transform;
+
+using android::hardware::graphics::composer::V2_1::IComposer;
+using android::hardware::graphics::composer::V2_1::IComposerCallback;
+using android::hardware::graphics::composer::V2_1::IComposerClient;
+using android::hardware::graphics::composer::V2_1::Error;
+using android::hardware::graphics::composer::V2_1::Display;
+using android::hardware::graphics::composer::V2_1::Layer;
+using android::hardware::graphics::composer::V2_1::Config;
+
+using android::hardware::graphics::composer::V2_1::CommandWriterBase;
+using android::hardware::graphics::composer::V2_1::CommandReaderBase;
+
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::MessageQueue;
+using android::hardware::MQDescriptorSync;
+using android::hardware::hidl_vec;
+using android::hardware::hidl_handle;
+
+class CommandReader : public CommandReaderBase {
+public:
+ ~CommandReader();
+
+ // Parse and execute commands from the command queue. The commands are
+ // actually return values from the server and will be saved in ReturnData.
+ Error parse();
+
+ // Get and clear saved errors.
+ struct CommandError {
+ uint32_t location;
+ Error error;
+ };
+ std::vector<CommandError> takeErrors();
+
+ bool hasChanges(Display display, uint32_t* outNumChangedCompositionTypes,
+ uint32_t* outNumLayerRequestMasks) const;
+
+ // Get and clear saved changed composition types.
+ void takeChangedCompositionTypes(Display display,
+ std::vector<Layer>* outLayers,
+ std::vector<IComposerClient::Composition>* outTypes);
+
+ // Get and clear saved display requests.
+ void takeDisplayRequests(Display display,
+ uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
+ std::vector<uint32_t>* outLayerRequestMasks);
+
+ // Get and clear saved release fences.
+ void takeReleaseFences(Display display, std::vector<Layer>* outLayers,
+ std::vector<int>* outReleaseFences);
+
+ // Get and clear saved present fence.
+ void takePresentFence(Display display, int* outPresentFence);
+
+ // Get what stage succeeded during PresentOrValidate: Present or Validate
+ void takePresentOrValidateStage(Display display, uint32_t * state);
+
+private:
+ void resetData();
+
+ bool parseSelectDisplay(uint16_t length);
+ bool parseSetError(uint16_t length);
+ bool parseSetChangedCompositionTypes(uint16_t length);
+ bool parseSetDisplayRequests(uint16_t length);
+ bool parseSetPresentFence(uint16_t length);
+ bool parseSetReleaseFences(uint16_t length);
+ bool parseSetPresentOrValidateDisplayResult(uint16_t length);
+
+ struct ReturnData {
+ uint32_t displayRequests = 0;
+
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ int presentFence = -1;
+
+ std::vector<Layer> releasedLayers;
+ std::vector<int> releaseFences;
+
+ uint32_t presentOrValidateState;
+ };
+
+ std::vector<CommandError> mErrors;
+ std::unordered_map<Display, ReturnData> mReturnData;
+
+ // When SELECT_DISPLAY is parsed, this is updated to point to the
+ // display's return data in mReturnData. We use it to avoid repeated
+ // map lookups.
+ ReturnData* mCurrentReturnData;
+};
+
+// Composer is a wrapper to IComposer, a proxy to server-side composer.
+class Composer {
+public:
+ Composer(bool useVrComposer);
+
+ std::vector<IComposer::Capability> getCapabilities();
+ std::string dumpDebugInfo();
+
+ void registerCallback(const sp<IComposerCallback>& callback);
+
+ // Returns true if the connected composer service is running in a remote
+ // process, false otherwise. This will return false if the service is
+ // configured in passthrough mode, for example.
+ bool isRemote();
+
+ // Reset all pending commands in the command buffer. Useful if you want to
+ // skip a frame but have already queued some commands.
+ void resetCommands();
+
+ uint32_t getMaxVirtualDisplayCount();
+ bool isUsingVrComposer() const { return mIsUsingVrComposer; }
+ Error createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay);
+ Error destroyVirtualDisplay(Display display);
+
+ Error acceptDisplayChanges(Display display);
+
+ Error createLayer(Display display, Layer* outLayer);
+ Error destroyLayer(Display display, Layer layer);
+
+ Error getActiveConfig(Display display, Config* outConfig);
+ Error getChangedCompositionTypes(Display display,
+ std::vector<Layer>* outLayers,
+ std::vector<IComposerClient::Composition>* outTypes);
+ Error getColorModes(Display display, std::vector<ColorMode>* outModes);
+ Error getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue);
+ Error getDisplayConfigs(Display display, std::vector<Config>* outConfigs);
+ Error getDisplayName(Display display, std::string* outName);
+
+ Error getDisplayRequests(Display display, uint32_t* outDisplayRequestMask,
+ std::vector<Layer>* outLayers,
+ std::vector<uint32_t>* outLayerRequestMasks);
+
+ Error getDisplayType(Display display,
+ IComposerClient::DisplayType* outType);
+ Error getDozeSupport(Display display, bool* outSupport);
+ Error getHdrCapabilities(Display display, std::vector<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance);
+
+ Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
+ std::vector<int>* outReleaseFences);
+
+ Error presentDisplay(Display display, int* outPresentFence);
+
+ Error setActiveConfig(Display display, Config config);
+
+ /*
+ * The composer caches client targets internally. When target is nullptr,
+ * the composer uses slot to look up the client target from its cache.
+ * When target is not nullptr, the cache is updated with the new target.
+ */
+ Error setClientTarget(Display display, uint32_t slot,
+ const sp<GraphicBuffer>& target,
+ int acquireFence, Dataspace dataspace,
+ const std::vector<IComposerClient::Rect>& damage);
+ Error setColorMode(Display display, ColorMode mode);
+ Error setColorTransform(Display display, const float* matrix,
+ ColorTransform hint);
+ Error setOutputBuffer(Display display, const native_handle_t* buffer,
+ int releaseFence);
+ Error setPowerMode(Display display, IComposerClient::PowerMode mode);
+ Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled);
+
+ Error setClientTargetSlotCount(Display display);
+
+ Error validateDisplay(Display display, uint32_t* outNumTypes,
+ uint32_t* outNumRequests);
+
+ Error presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
+ uint32_t* outNumRequests,
+ int* outPresentFence,
+ uint32_t* state);
+
+ Error setCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y);
+ /* see setClientTarget for the purpose of slot */
+ Error setLayerBuffer(Display display, Layer layer, uint32_t slot,
+ const sp<GraphicBuffer>& buffer, int acquireFence);
+ Error setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& damage);
+ Error setLayerBlendMode(Display display, Layer layer,
+ IComposerClient::BlendMode mode);
+ Error setLayerColor(Display display, Layer layer,
+ const IComposerClient::Color& color);
+ Error setLayerCompositionType(Display display, Layer layer,
+ IComposerClient::Composition type);
+ Error setLayerDataspace(Display display, Layer layer,
+ Dataspace dataspace);
+ Error setLayerDisplayFrame(Display display, Layer layer,
+ const IComposerClient::Rect& frame);
+ Error setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha);
+ Error setLayerSidebandStream(Display display, Layer layer,
+ const native_handle_t* stream);
+ Error setLayerSourceCrop(Display display, Layer layer,
+ const IComposerClient::FRect& crop);
+ Error setLayerTransform(Display display, Layer layer,
+ Transform transform);
+ Error setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<IComposerClient::Rect>& visible);
+ Error setLayerZOrder(Display display, Layer layer, uint32_t z);
+ Error setLayerInfo(Display display, Layer layer, uint32_t type,
+ uint32_t appId);
+private:
+ class CommandWriter : public CommandWriterBase {
+ public:
+ CommandWriter(uint32_t initialMaxSize);
+ ~CommandWriter() override;
+
+ void setLayerInfo(uint32_t type, uint32_t appId);
+ void setClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
+ void setLayerBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
+
+ private:
+ void writeBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
+ };
+
+ // Many public functions above simply write a command into the command
+ // queue to batch the calls. validateDisplay and presentDisplay will call
+ // this function to execute the command queue.
+ Error execute();
+
+ sp<IComposer> mComposer;
+ sp<IComposerClient> mClient;
+
+ // 64KiB minus a small space for metadata such as read/write pointers
+ static constexpr size_t kWriterInitialSize =
+ 64 * 1024 / sizeof(uint32_t) - 16;
+ CommandWriter mWriter;
+ CommandReader mReader;
+
+ // When true, the we attach to the vr_hwcomposer service instead of the
+ // hwcomposer. This allows us to redirect surfaces to 3d surfaces in vr.
+ const bool mIsUsingVrComposer;
+};
+
+} // namespace Hwc2
+
+} // namespace android
+
+#endif // ANDROID_SF_COMPOSER_HAL_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/GrallocUsageConversion.cpp
^
|
+(symlink to ../../hybris/gralloc/GrallocUsageConversion.cpp)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/HWC2.cpp
^
|
@@ -0,0 +1,889 @@
+/*
+ * Copyright 2015 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.
+ */
+
+// #define LOG_NDEBUG 0
+
+#undef LOG_TAG
+#define LOG_TAG "HWC2"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "HWC2.h"
+#include "ComposerHal.h"
+
+#include <ui/Fence.h>
+#include <ui/FloatRect.h>
+#include <ui/GraphicBuffer.h>
+#if ANDROID_VERSION_MAJOR >= 9
+#include <ui/GraphicTypes.h>
+#endif
+#include <ui/Region.h>
+
+#include <android/configuration.h>
+
+#include <algorithm>
+#include <inttypes.h>
+
+using android::Fence;
+using android::FloatRect;
+using android::GraphicBuffer;
+using android::HdrCapabilities;
+using android::Rect;
+using android::Region;
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+
+namespace HWC2 {
+
+namespace Hwc2 = android::Hwc2;
+
+namespace {
+
+class ComposerCallbackBridge : public Hwc2::IComposerCallback {
+public:
+ ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
+ : mCallback(callback), mSequenceId(sequenceId),
+ mHasPrimaryDisplay(false) {}
+
+ Return<void> onHotplug(Hwc2::Display display,
+ IComposerCallback::Connection conn) override
+ {
+ HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
+ if (!mHasPrimaryDisplay) {
+ LOG_ALWAYS_FATAL_IF(connection != HWC2::Connection::Connected,
+ "Initial onHotplug callback should be "
+ "primary display connected");
+ mHasPrimaryDisplay = true;
+ mCallback->onHotplugReceived(mSequenceId, display,
+ connection, true);
+ } else {
+ mCallback->onHotplugReceived(mSequenceId, display,
+ connection, false);
+ }
+ return Void();
+ }
+
+ Return<void> onRefresh(Hwc2::Display display) override
+ {
+ mCallback->onRefreshReceived(mSequenceId, display);
+ return Void();
+ }
+
+ Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
+ {
+ mCallback->onVsyncReceived(mSequenceId, display, timestamp);
+ return Void();
+ }
+
+ bool HasPrimaryDisplay() { return mHasPrimaryDisplay; }
+
+private:
+ ComposerCallback* mCallback;
+ int32_t mSequenceId;
+ bool mHasPrimaryDisplay;
+};
+
+} // namespace anonymous
+
+
+// Device methods
+
+Device::Device(bool useVrComposer)
+ : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
+ mCapabilities(),
+ mDisplays(),
+ mRegisteredCallback(false)
+{
+ loadCapabilities();
+}
+
+void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
+ if (mRegisteredCallback) {
+ ALOGW("Callback already registered. Ignored extra registration "
+ "attempt.");
+ return;
+ }
+ mRegisteredCallback = true;
+ sp<ComposerCallbackBridge> callbackBridge(
+ new ComposerCallbackBridge(callback, sequenceId));
+ mComposer->registerCallback(callbackBridge);
+ LOG_ALWAYS_FATAL_IF(!callbackBridge->HasPrimaryDisplay(),
+ "Registered composer callback but didn't get primary display");
+}
+
+// Required by HWC2 device
+
+std::string Device::dump() const
+{
+ return mComposer->dumpDebugInfo();
+}
+
+uint32_t Device::getMaxVirtualDisplayCount() const
+{
+ return mComposer->getMaxVirtualDisplayCount();
+}
+
+Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
+ android_pixel_format_t* format, Display** outDisplay)
+{
+ ALOGI("Creating virtual display");
+
+ hwc2_display_t displayId = 0;
+ auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
+ auto intError = mComposer->createVirtualDisplay(width, height,
+ &intFormat, &displayId);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ auto display = std::make_unique<Display>(
+ *mComposer.get(), mCapabilities, displayId, DisplayType::Virtual);
+ *outDisplay = display.get();
+ *format = static_cast<android_pixel_format_t>(intFormat);
+ mDisplays.emplace(displayId, std::move(display));
+ ALOGI("Created virtual display");
+ return Error::None;
+}
+
+void Device::destroyDisplay(hwc2_display_t displayId)
+{
+ ALOGI("Destroying display %" PRIu64, displayId);
+ mDisplays.erase(displayId);
+}
+
+void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
+ if (connection == Connection::Connected) {
+ auto display = getDisplayById(displayId);
+ if (display) {
+ if (display->isConnected()) {
+ ALOGW("Attempt to hotplug connect display %" PRIu64
+ " , which is already connected.", displayId);
+ } else {
+ display->setConnected(true);
+ }
+ } else {
+ DisplayType displayType;
+ auto intError = mComposer->getDisplayType(displayId,
+ reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
+ &displayType));
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
+ "Aborting hotplug attempt.",
+ displayId, to_string(error).c_str(), intError);
+ return;
+ }
+
+ auto newDisplay = std::make_unique<Display>(
+ *mComposer.get(), mCapabilities, displayId, displayType);
+ mDisplays.emplace(displayId, std::move(newDisplay));
+ }
+ } else if (connection == Connection::Disconnected) {
+ // The display will later be destroyed by a call to
+ // destroyDisplay(). For now we just mark it disconnected.
+ auto display = getDisplayById(displayId);
+ if (display) {
+ display->setConnected(false);
+ } else {
+ ALOGW("Attempted to disconnect unknown display %" PRIu64,
+ displayId);
+ }
+ }
+}
+
+// Other Device methods
+
+Display* Device::getDisplayById(hwc2_display_t id) {
+ auto iter = mDisplays.find(id);
+ return iter == mDisplays.end() ? nullptr : iter->second.get();
+}
+
+// Device initialization methods
+
+void Device::loadCapabilities()
+{
+ static_assert(sizeof(Capability) == sizeof(int32_t),
+ "Capability size has changed");
+ auto capabilities = mComposer->getCapabilities();
+ for (auto capability : capabilities) {
+ mCapabilities.emplace(static_cast<Capability>(capability));
+ }
+}
+
+// Display methods
+
+Display::Display(android::Hwc2::Composer& composer,
+ const std::unordered_set<Capability>& capabilities,
+ hwc2_display_t id, DisplayType type)
+ : mComposer(composer),
+ mCapabilities(capabilities),
+ mId(id),
+ mIsConnected(false),
+ mType(type)
+{
+ ALOGV("Created display %" PRIu64, id);
+ setConnected(true);
+}
+
+Display::~Display() {
+ mLayers.clear();
+
+ if (mType == DisplayType::Virtual) {
+ ALOGV("Destroying virtual display");
+ auto intError = mComposer.destroyVirtualDisplay(mId);
+ auto error = static_cast<Error>(intError);
+ ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64
+ ") failed: %s (%d)", mId, to_string(error).c_str(), intError);
+ } else if (mType == DisplayType::Physical) {
+ auto error = setVsyncEnabled(HWC2::Vsync::Disable);
+ if (error != Error::None) {
+ ALOGE("~Display: Failed to disable vsync for display %" PRIu64
+ ": %s (%d)", mId, to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
+ }
+}
+
+Display::Config::Config(Display& display, hwc2_config_t id)
+ : mDisplay(display),
+ mId(id),
+ mWidth(-1),
+ mHeight(-1),
+ mVsyncPeriod(-1),
+ mDpiX(-1),
+ mDpiY(-1) {}
+
+Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
+ : mConfig(new Config(display, id)) {}
+
+float Display::Config::Builder::getDefaultDensity() {
+ // Default density is based on TVs: 1080p displays get XHIGH density, lower-
+ // resolution displays get TV density. Maybe eventually we'll need to update
+ // it for 4k displays, though hopefully those will just report accurate DPI
+ // information to begin with. This is also used for virtual displays and
+ // older HWC implementations, so be careful about orientation.
+
+ auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
+ if (longDimension >= 1080) {
+ return ACONFIGURATION_DENSITY_XHIGH;
+ } else {
+ return ACONFIGURATION_DENSITY_TV;
+ }
+}
+
+// Required by HWC2 display
+
+Error Display::acceptChanges()
+{
+ auto intError = mComposer.acceptDisplayChanges(mId);
+ return static_cast<Error>(intError);
+}
+
+Error Display::createLayer(Layer** outLayer)
+{
+ if (!outLayer) {
+ return Error::BadParameter;
+ }
+ hwc2_layer_t layerId = 0;
+ auto intError = mComposer.createLayer(mId, &layerId);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ auto layer = std::make_unique<Layer>(
+ mComposer, mCapabilities, mId, layerId);
+ *outLayer = layer.get();
+ mLayers.emplace(layerId, std::move(layer));
+ return Error::None;
+}
+
+Error Display::destroyLayer(Layer* layer)
+{
+ if (!layer) {
+ return Error::BadParameter;
+ }
+ mLayers.erase(layer->getId());
+ return Error::None;
+}
+
+Error Display::getActiveConfig(
+ std::shared_ptr<const Display::Config>* outConfig) const
+{
+ ALOGV("[%" PRIu64 "] getActiveConfig", mId);
+ hwc2_config_t configId = 0;
+ auto intError = mComposer.getActiveConfig(mId, &configId);
+ auto error = static_cast<Error>(intError);
+
+ if (error != Error::None) {
+ ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
+ *outConfig = nullptr;
+ return error;
+ }
+
+ if (mConfigs.count(configId) != 0) {
+ *outConfig = mConfigs.at(configId);
+ } else {
+ ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
+ configId);
+ // Return no error, but the caller needs to check for a null pointer to
+ // detect this case
+ *outConfig = nullptr;
+ }
+
+ return Error::None;
+}
+
+Error Display::getChangedCompositionTypes(
+ std::unordered_map<Layer*, Composition>* outTypes)
+{
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<Hwc2::IComposerClient::Composition> types;
+ auto intError = mComposer.getChangedCompositionTypes(
+ mId, &layerIds, &types);
+ uint32_t numElements = layerIds.size();
+ auto error = static_cast<Error>(intError);
+ error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ outTypes->clear();
+ outTypes->reserve(numElements);
+ for (uint32_t element = 0; element < numElements; ++element) {
+ auto layer = getLayerById(layerIds[element]);
+ if (layer) {
+ auto type = static_cast<Composition>(types[element]);
+ ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
+ layer->getId(), to_string(type).c_str());
+ outTypes->emplace(layer, type);
+ } else {
+ ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
+ " on display %" PRIu64, layerIds[element], mId);
+ }
+ }
+
+ return Error::None;
+}
+
+Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
+{
+ std::vector<Hwc2::ColorMode> modes;
+ auto intError = mComposer.getColorModes(mId, &modes);
+ uint32_t numModes = modes.size();
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ outModes->resize(numModes);
+ for (size_t i = 0; i < numModes; i++) {
+ (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
+ }
+ return Error::None;
+}
+
+std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
+{
+ std::vector<std::shared_ptr<const Config>> configs;
+ for (const auto& element : mConfigs) {
+ configs.emplace_back(element.second);
+ }
+ return configs;
+}
+
+Error Display::getName(std::string* outName) const
+{
+ auto intError = mComposer.getDisplayName(mId, outName);
+ return static_cast<Error>(intError);
+}
+
+Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
+ std::unordered_map<Layer*, LayerRequest>* outLayerRequests)
+{
+ uint32_t intDisplayRequests;
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<uint32_t> layerRequests;
+ auto intError = mComposer.getDisplayRequests(
+ mId, &intDisplayRequests, &layerIds, &layerRequests);
+ uint32_t numElements = layerIds.size();
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
+ outLayerRequests->clear();
+ outLayerRequests->reserve(numElements);
+ for (uint32_t element = 0; element < numElements; ++element) {
+ auto layer = getLayerById(layerIds[element]);
+ if (layer) {
+ auto layerRequest =
+ static_cast<LayerRequest>(layerRequests[element]);
+ outLayerRequests->emplace(layer, layerRequest);
+ } else {
+ ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
+ PRIu64, layerIds[element], mId);
+ }
+ }
+
+ return Error::None;
+}
+
+Error Display::getType(DisplayType* outType) const
+{
+ *outType = mType;
+ return Error::None;
+}
+
+Error Display::supportsDoze(bool* outSupport) const
+{
+ bool intSupport = false;
+ auto intError = mComposer.getDozeSupport(mId, &intSupport);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+ *outSupport = static_cast<bool>(intSupport);
+ return Error::None;
+}
+
+Error Display::getHdrCapabilities(
+ std::unique_ptr<HdrCapabilities>* outCapabilities) const
+{
+ uint32_t numTypes = 0;
+ float maxLuminance = -1.0f;
+ float maxAverageLuminance = -1.0f;
+ float minLuminance = -1.0f;
+ std::vector<Hwc2::Hdr> intTypes;
+ auto intError = mComposer.getHdrCapabilities(mId, &intTypes,
+ &maxLuminance, &maxAverageLuminance, &minLuminance);
+ auto error = static_cast<HWC2::Error>(intError);
+
+#if ANDROID_VERSION_MAJOR >= 9
+ std::vector<android::ui::Hdr> types;
+ for (auto type : intTypes) {
+ types.push_back(static_cast<android::ui::Hdr>(type));
+ }
+#else
+ std::vector<int32_t> types;
+ for (auto type : intTypes) {
+ types.push_back(static_cast<int32_t>(type));
+ }
+#endif
+ numTypes = types.size();
+ if (error != Error::None) {
+ return error;
+ }
+
+ *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
+ maxLuminance, maxAverageLuminance, minLuminance);
+ return Error::None;
+}
+
+Error Display::getReleaseFences(
+ std::unordered_map<Layer*, sp<Fence>>* outFences) const
+{
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<int> fenceFds;
+ auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
+ auto error = static_cast<Error>(intError);
+ uint32_t numElements = layerIds.size();
+ if (error != Error::None) {
+ return error;
+ }
+
+ std::unordered_map<Layer*, sp<Fence>> releaseFences;
+ releaseFences.reserve(numElements);
+ for (uint32_t element = 0; element < numElements; ++element) {
+ auto layer = getLayerById(layerIds[element]);
+ if (layer) {
+ sp<Fence> fence(new Fence(fenceFds[element]));
+ releaseFences.emplace(layer, fence);
+ } else {
+ ALOGE("getReleaseFences: invalid layer %" PRIu64
+ " found on display %" PRIu64, layerIds[element], mId);
+ for (; element < numElements; ++element) {
+ close(fenceFds[element]);
+ }
+ return Error::BadLayer;
+ }
+ }
+
+ *outFences = std::move(releaseFences);
+ return Error::None;
+}
+
+Error Display::present(sp<Fence>* outPresentFence)
+{
+ int32_t presentFenceFd = -1;
+ auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ return error;
+ }
+
+ *outPresentFence = new Fence(presentFenceFd);
+ return Error::None;
+}
+
+Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
+{
+ if (config->getDisplayId() != mId) {
+ ALOGE("setActiveConfig received config %u for the wrong display %"
+ PRIu64 " (expected %" PRIu64 ")", config->getId(),
+ config->getDisplayId(), mId);
+ return Error::BadConfig;
+ }
+ auto intError = mComposer.setActiveConfig(mId, config->getId());
+ return static_cast<Error>(intError);
+}
+
+Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
+ const sp<Fence>& acquireFence, android_dataspace_t dataspace)
+{
+ // TODO: Properly encode client target surface damage
+ int32_t fenceFd = acquireFence->dup();
+ auto intError = mComposer.setClientTarget(mId, slot, target,
+ fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
+ std::vector<Hwc2::IComposerClient::Rect>());
+ return static_cast<Error>(intError);
+}
+
+Error Display::setColorMode(android_color_mode_t mode)
+{
+ auto intError = mComposer.setColorMode(
+ mId, static_cast<Hwc2::ColorMode>(mode));
+ return static_cast<Error>(intError);
+}
+
+Error Display::setColorTransform(const android::mat4& matrix,
+ android_color_transform_t hint)
+{
+ auto intError = mComposer.setColorTransform(mId,
+ matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
+ return static_cast<Error>(intError);
+}
+
+Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence)
+{
+ int32_t fenceFd = releaseFence->dup();
+ auto handle = buffer->getNativeBuffer()->handle;
+ auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
+ close(fenceFd);
+ return static_cast<Error>(intError);
+}
+
+Error Display::setPowerMode(PowerMode mode)
+{
+ auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
+ auto intError = mComposer.setPowerMode(mId, intMode);
+ return static_cast<Error>(intError);
+}
+
+Error Display::setVsyncEnabled(Vsync enabled)
+{
+ auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
+ auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
+ return static_cast<Error>(intError);
+}
+
+Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
+{
+ uint32_t numTypes = 0;
+ uint32_t numRequests = 0;
+ auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None && error != Error::HasChanges) {
+ return error;
+ }
+
+ *outNumTypes = numTypes;
+ *outNumRequests = numRequests;
+ return error;
+}
+
+Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
+ sp<android::Fence>* outPresentFence, uint32_t* state) {
+
+ uint32_t numTypes = 0;
+ uint32_t numRequests = 0;
+ int32_t presentFenceFd = -1;
+ auto intError = mComposer.presentOrValidateDisplay(
+ mId, &numTypes, &numRequests, &presentFenceFd, state);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None && error != Error::HasChanges) {
+ return error;
+ }
+
+ if (*state == 1) {
+ *outPresentFence = new Fence(presentFenceFd);
+ }
+
+ if (*state == 0) {
+ *outNumTypes = numTypes;
+ *outNumRequests = numRequests;
+ }
+ return error;
+}
+
+void Display::discardCommands()
+{
+ mComposer.resetCommands();
+}
+
+// For use by Device
+
+void Display::setConnected(bool connected) {
+ if (!mIsConnected && connected && mType == DisplayType::Physical) {
+ mComposer.setClientTargetSlotCount(mId);
+ loadConfigs();
+ }
+ mIsConnected = connected;
+}
+
+int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
+{
+ int32_t value = 0;
+ auto intError = mComposer.getDisplayAttribute(mId, configId,
+ static_cast<Hwc2::IComposerClient::Attribute>(attribute),
+ &value);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
+ configId, to_string(attribute).c_str(),
+ to_string(error).c_str(), intError);
+ return -1;
+ }
+ return value;
+}
+
+void Display::loadConfig(hwc2_config_t configId)
+{
+ ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
+
+ auto config = Config::Builder(*this, configId)
+ .setWidth(getAttribute(configId, Attribute::Width))
+ .setHeight(getAttribute(configId, Attribute::Height))
+ .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
+ .setDpiX(getAttribute(configId, Attribute::DpiX))
+ .setDpiY(getAttribute(configId, Attribute::DpiY))
+ .build();
+ mConfigs.emplace(configId, std::move(config));
+}
+
+void Display::loadConfigs()
+{
+ ALOGV("[%" PRIu64 "] loadConfigs", mId);
+
+ std::vector<Hwc2::Config> configIds;
+ auto intError = mComposer.getDisplayConfigs(mId, &configIds);
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
+ to_string(error).c_str(), intError);
+ return;
+ }
+
+ for (auto configId : configIds) {
+ loadConfig(configId);
+ }
+}
+
+// Other Display methods
+
+Layer* Display::getLayerById(hwc2_layer_t id) const
+{
+ if (mLayers.count(id) == 0) {
+ return nullptr;
+ }
+
+ return mLayers.at(id).get();
+}
+
+// Layer methods
+
+Layer::Layer(android::Hwc2::Composer& composer,
+ const std::unordered_set<Capability>& capabilities,
+ hwc2_display_t displayId, hwc2_layer_t layerId)
+ : mComposer(composer),
+ mCapabilities(capabilities),
+ mDisplayId(displayId),
+ mId(layerId)
+{
+ ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId);
+}
+
+Layer::~Layer()
+{
+ auto intError = mComposer.destroyLayer(mDisplayId, mId);
+ auto error = static_cast<Error>(intError);
+ ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
+ " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
+ intError);
+ if (mLayerDestroyedListener) {
+ mLayerDestroyedListener(this);
+ }
+}
+
+void Layer::setLayerDestroyedListener(std::function<void(Layer*)> listener) {
+ LOG_ALWAYS_FATAL_IF(mLayerDestroyedListener && listener,
+ "Attempt to set layer destroyed listener multiple times");
+ mLayerDestroyedListener = listener;
+}
+
+Error Layer::setCursorPosition(int32_t x, int32_t y)
+{
+ auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& acquireFence)
+{
+ int32_t fenceFd = acquireFence->dup();
+ auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer,
+ fenceFd);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setSurfaceDamage(const Region& damage)
+{
+ // We encode default full-screen damage as INVALID_RECT upstream, but as 0
+ // rects for HWC
+ Hwc2::Error intError = Hwc2::Error::NONE;
+ if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
+ intError = mComposer.setLayerSurfaceDamage(mDisplayId,
+ mId, std::vector<Hwc2::IComposerClient::Rect>());
+ } else {
+ size_t rectCount = 0;
+ auto rectArray = damage.getArray(&rectCount);
+
+ std::vector<Hwc2::IComposerClient::Rect> hwcRects;
+ for (size_t rect = 0; rect < rectCount; ++rect) {
+ hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
+ rectArray[rect].right, rectArray[rect].bottom});
+ }
+
+ intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects);
+ }
+
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setBlendMode(BlendMode mode)
+{
+ auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
+ auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setColor(hwc_color_t color)
+{
+ Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
+ auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setCompositionType(Composition type)
+{
+ auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
+ auto intError = mComposer.setLayerCompositionType(
+ mDisplayId, mId, intType);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setDataspace(android_dataspace_t dataspace)
+{
+ if (dataspace == mDataSpace) {
+ return Error::None;
+ }
+ mDataSpace = dataspace;
+ auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
+ auto intError = mComposer.setLayerDataspace(mDisplayId, mId, intDataspace);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setDisplayFrame(const Rect& frame)
+{
+ Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
+ frame.right, frame.bottom};
+ auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setPlaneAlpha(float alpha)
+{
+ auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setSidebandStream(const native_handle_t* stream)
+{
+ if (mCapabilities.count(Capability::SidebandStream) == 0) {
+ ALOGE("Attempted to call setSidebandStream without checking that the "
+ "device supports sideband streams");
+ return Error::Unsupported;
+ }
+ auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setSourceCrop(const FloatRect& crop)
+{
+ Hwc2::IComposerClient::FRect hwcRect{
+ crop.left, crop.top, crop.right, crop.bottom};
+ auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setTransform(Transform transform)
+{
+ auto intTransform = static_cast<Hwc2::Transform>(transform);
+ auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setVisibleRegion(const Region& region)
+{
+ size_t rectCount = 0;
+ auto rectArray = region.getArray(&rectCount);
+
+ std::vector<Hwc2::IComposerClient::Rect> hwcRects;
+ for (size_t rect = 0; rect < rectCount; ++rect) {
+ hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
+ rectArray[rect].right, rectArray[rect].bottom});
+ }
+
+ auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setZOrder(uint32_t z)
+{
+ auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z);
+ return static_cast<Error>(intError);
+}
+
+Error Layer::setInfo(uint32_t type, uint32_t appId)
+{
+ auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId);
+ return static_cast<Error>(intError);
+}
+
+} // namespace HWC2
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/HWC2.h
^
|
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2015 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.
+ */
+
+#ifndef ANDROID_SF_HWC2_H
+#define ANDROID_SF_HWC2_H
+
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
+#include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
+
+#include <ui/HdrCapabilities.h>
+#include <math/mat4.h>
+
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
+#include <functional>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <map>
+
+namespace android {
+ class Fence;
+ class FloatRect;
+ class GraphicBuffer;
+ class Rect;
+ class Region;
+ namespace Hwc2 {
+ class Composer;
+ }
+}
+
+namespace HWC2 {
+
+class Display;
+class Layer;
+
+// Implement this interface to receive hardware composer events.
+//
+// These callback functions will generally be called on a hwbinder thread, but
+// when first registering the callback the onHotplugReceived() function will
+// immediately be called on the thread calling registerCallback().
+//
+// All calls receive a sequenceId, which will be the value that was supplied to
+// HWC2::Device::registerCallback(). It's used to help differentiate callbacks
+// from different hardware composer instances.
+class ComposerCallback {
+ public:
+ virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
+ Connection connection,
+ bool primaryDisplay) = 0;
+ virtual void onRefreshReceived(int32_t sequenceId,
+ hwc2_display_t display) = 0;
+ virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
+ int64_t timestamp) = 0;
+ virtual ~ComposerCallback() = default;
+};
+
+// C++ Wrapper around hwc2_device_t. Load all functions pointers
+// and handle callback registration.
+class Device
+{
+public:
+ // useVrComposer is passed to the composer HAL. When true, the composer HAL
+ // will use the vr composer service, otherwise it uses the real hardware
+ // composer.
+ Device(bool useVrComposer);
+
+ void registerCallback(ComposerCallback* callback, int32_t sequenceId);
+
+ // Required by HWC2
+
+ std::string dump() const;
+
+ const std::unordered_set<Capability>& getCapabilities() const {
+ return mCapabilities;
+ };
+
+ uint32_t getMaxVirtualDisplayCount() const;
+ Error createVirtualDisplay(uint32_t width, uint32_t height,
+ android_pixel_format_t* format, Display** outDisplay);
+ void destroyDisplay(hwc2_display_t displayId);
+
+ void onHotplug(hwc2_display_t displayId, Connection connection);
+
+ // Other Device methods
+
+ Display* getDisplayById(hwc2_display_t id);
+
+ android::Hwc2::Composer* getComposer() { return mComposer.get(); }
+
+private:
+ // Initialization methods
+
+ void loadCapabilities();
+
+ // Member variables
+ std::unique_ptr<android::Hwc2::Composer> mComposer;
+ std::unordered_set<Capability> mCapabilities;
+ std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
+ bool mRegisteredCallback;
+};
+
+// Convenience C++ class to access hwc2_device_t Display functions directly.
+class Display
+{
+public:
+ Display(android::Hwc2::Composer& composer,
+ const std::unordered_set<Capability>& capabilities,
+ hwc2_display_t id, DisplayType type);
+ ~Display();
+
+ class Config
+ {
+ public:
+ class Builder
+ {
+ public:
+ Builder(Display& display, hwc2_config_t id);
+
+ std::shared_ptr<const Config> build() {
+ return std::const_pointer_cast<const Config>(
+ std::move(mConfig));
+ }
+
+ Builder& setWidth(int32_t width) {
+ mConfig->mWidth = width;
+ return *this;
+ }
+ Builder& setHeight(int32_t height) {
+ mConfig->mHeight = height;
+ return *this;
+ }
+ Builder& setVsyncPeriod(int32_t vsyncPeriod) {
+ mConfig->mVsyncPeriod = vsyncPeriod;
+ return *this;
+ }
+ Builder& setDpiX(int32_t dpiX) {
+ if (dpiX == -1) {
+ mConfig->mDpiX = getDefaultDensity();
+ } else {
+ mConfig->mDpiX = dpiX / 1000.0f;
+ }
+ return *this;
+ }
+ Builder& setDpiY(int32_t dpiY) {
+ if (dpiY == -1) {
+ mConfig->mDpiY = getDefaultDensity();
+ } else {
+ mConfig->mDpiY = dpiY / 1000.0f;
+ }
+ return *this;
+ }
+
+ private:
+ float getDefaultDensity();
+ std::shared_ptr<Config> mConfig;
+ };
+
+ hwc2_display_t getDisplayId() const { return mDisplay.getId(); }
+ hwc2_config_t getId() const { return mId; }
+
+ int32_t getWidth() const { return mWidth; }
+ int32_t getHeight() const { return mHeight; }
+ nsecs_t getVsyncPeriod() const { return mVsyncPeriod; }
+ float getDpiX() const { return mDpiX; }
+ float getDpiY() const { return mDpiY; }
+
+ private:
+ Config(Display& display, hwc2_config_t id);
+
+ Display& mDisplay;
+ hwc2_config_t mId;
+
+ int32_t mWidth;
+ int32_t mHeight;
+ nsecs_t mVsyncPeriod;
+ float mDpiX;
+ float mDpiY;
+ };
+
+ // Required by HWC2
+
+ [[clang::warn_unused_result]] Error acceptChanges();
+ [[clang::warn_unused_result]] Error createLayer(Layer** outLayer);
+ [[clang::warn_unused_result]] Error destroyLayer(Layer* layer);
+ [[clang::warn_unused_result]] Error getActiveConfig(
+ std::shared_ptr<const Config>* outConfig) const;
+ [[clang::warn_unused_result]] Error getChangedCompositionTypes(
+ std::unordered_map<Layer*, Composition>* outTypes);
+ [[clang::warn_unused_result]] Error getColorModes(
+ std::vector<android_color_mode_t>* outModes) const;
+
+ // Doesn't call into the HWC2 device, so no errors are possible
+ std::vector<std::shared_ptr<const Config>> getConfigs() const;
+
+ [[clang::warn_unused_result]] Error getName(std::string* outName) const;
+ [[clang::warn_unused_result]] Error getRequests(
+ DisplayRequest* outDisplayRequests,
+ std::unordered_map<Layer*, LayerRequest>* outLayerRequests);
+ [[clang::warn_unused_result]] Error getType(DisplayType* outType) const;
+ [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const;
+ [[clang::warn_unused_result]] Error getHdrCapabilities(
+ std::unique_ptr<android::HdrCapabilities>* outCapabilities) const;
+ [[clang::warn_unused_result]] Error getReleaseFences(
+ std::unordered_map<Layer*,
+ android::sp<android::Fence>>* outFences) const;
+ [[clang::warn_unused_result]] Error present(
+ android::sp<android::Fence>* outPresentFence);
+ [[clang::warn_unused_result]] Error setActiveConfig(
+ const std::shared_ptr<const Config>& config);
+ [[clang::warn_unused_result]] Error setClientTarget(
+ uint32_t slot, const android::sp<android::GraphicBuffer>& target,
+ const android::sp<android::Fence>& acquireFence,
+ android_dataspace_t dataspace);
+ [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
+ [[clang::warn_unused_result]] Error setColorTransform(
+ const android::mat4& matrix, android_color_transform_t hint);
+ [[clang::warn_unused_result]] Error setOutputBuffer(
+ const android::sp<android::GraphicBuffer>& buffer,
+ const android::sp<android::Fence>& releaseFence);
+ [[clang::warn_unused_result]] Error setPowerMode(PowerMode mode);
+ [[clang::warn_unused_result]] Error setVsyncEnabled(Vsync enabled);
+ [[clang::warn_unused_result]] Error validate(uint32_t* outNumTypes,
+ uint32_t* outNumRequests);
+ [[clang::warn_unused_result]] Error presentOrValidate(uint32_t* outNumTypes,
+ uint32_t* outNumRequests,
+ android::sp<android::Fence>* outPresentFence, uint32_t* state);
+
+ // Most methods in this class write a command to a command buffer. The
+ // command buffer is implicitly submitted in validate, present, and
+ // presentOrValidate. This method provides a way to discard the commands,
+ // which can be used to discard stale commands.
+ void discardCommands();
+
+ // Other Display methods
+
+ hwc2_display_t getId() const { return mId; }
+ bool isConnected() const { return mIsConnected; }
+ void setConnected(bool connected); // For use by Device only
+
+private:
+ int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
+ void loadConfig(hwc2_config_t configId);
+ void loadConfigs();
+
+ // This may fail (and return a null pointer) if no layer with this ID exists
+ // on this display
+ Layer* getLayerById(hwc2_layer_t id) const;
+
+ // Member variables
+
+ // These are references to data owned by HWC2::Device, which will outlive
+ // this HWC2::Display, so these references are guaranteed to be valid for
+ // the lifetime of this object.
+ android::Hwc2::Composer& mComposer;
+ const std::unordered_set<Capability>& mCapabilities;
+
+ hwc2_display_t mId;
+ bool mIsConnected;
+ DisplayType mType;
+ std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
+ // The ordering in this map matters, for getConfigs(), when it is
+ // converted to a vector
+ std::map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
+};
+
+// Convenience C++ class to access hwc2_device_t Layer functions directly.
+class Layer
+{
+public:
+ Layer(android::Hwc2::Composer& composer,
+ const std::unordered_set<Capability>& capabilities,
+ hwc2_display_t displayId, hwc2_layer_t layerId);
+ ~Layer();
+
+ hwc2_layer_t getId() const { return mId; }
+
+ // Register a listener to be notified when the layer is destroyed. When the
+ // listener function is called, the Layer will be in the process of being
+ // destroyed, so it's not safe to call methods on it.
+ void setLayerDestroyedListener(std::function<void(Layer*)> listener);
+
+ [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
+ [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
+ const android::sp<android::GraphicBuffer>& buffer,
+ const android::sp<android::Fence>& acquireFence);
+ [[clang::warn_unused_result]] Error setSurfaceDamage(
+ const android::Region& damage);
+
+ [[clang::warn_unused_result]] Error setBlendMode(BlendMode mode);
+ [[clang::warn_unused_result]] Error setColor(hwc_color_t color);
+ [[clang::warn_unused_result]] Error setCompositionType(Composition type);
+ [[clang::warn_unused_result]] Error setDataspace(
+ android_dataspace_t dataspace);
+ [[clang::warn_unused_result]] Error setDisplayFrame(
+ const android::Rect& frame);
+ [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
+ [[clang::warn_unused_result]] Error setSidebandStream(
+ const native_handle_t* stream);
+ [[clang::warn_unused_result]] Error setSourceCrop(
+ const android::FloatRect& crop);
+ [[clang::warn_unused_result]] Error setTransform(Transform transform);
+ [[clang::warn_unused_result]] Error setVisibleRegion(
+ const android::Region& region);
+ [[clang::warn_unused_result]] Error setZOrder(uint32_t z);
+ [[clang::warn_unused_result]] Error setInfo(uint32_t type, uint32_t appId);
+
+private:
+ // These are references to data owned by HWC2::Device, which will outlive
+ // this HWC2::Layer, so these references are guaranteed to be valid for
+ // the lifetime of this object.
+ android::Hwc2::Composer& mComposer;
+ const std::unordered_set<Capability>& mCapabilities;
+
+ hwc2_display_t mDisplayId;
+ hwc2_layer_t mId;
+ android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
+ std::function<void(Layer*)> mLayerDestroyedListener;
+};
+
+} // namespace HWC2
+
+#endif // ANDROID_SF_HWC2_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/hwc2_compatibility_layer.cpp
^
|
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2018 TheKit <nekit1000@gmail.com>
+ *
+ * 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.
+ */
+
+#include <ui/Fence.h>
+#include <ui/FloatRect.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Region.h>
+#include <sync/sync.h>
+
+#include "HWC2.h"
+#include "hwc2_compatibility_layer.h"
+
+class HWComposerCallback : public HWC2::ComposerCallback
+{
+public:
+ HWComposerCallback(HWC2EventListener* listener);
+
+ void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
+ int64_t timestamp) override;
+ void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
+ HWC2::Connection connection,
+ bool primaryDisplay) override;
+ void onRefreshReceived(int32_t sequenceId,
+ hwc2_display_t display) override;
+private:
+ HWC2EventListener *listener;
+};
+
+HWComposerCallback::HWComposerCallback(HWC2EventListener* listener) :
+ listener(listener)
+{
+}
+
+void HWComposerCallback::onVsyncReceived(int32_t sequenceId,
+ hwc2_display_t display,
+ int64_t timestamp)
+{
+ listener->on_vsync_received(listener, sequenceId, display, timestamp);
+}
+
+void HWComposerCallback::onHotplugReceived(int32_t sequenceId,
+ hwc2_display_t display,
+ HWC2::Connection connection,
+ bool primaryDisplay)
+{
+ listener->on_hotplug_received(listener, sequenceId, display,
+ connection == HWC2::Connection::Connected,
+ primaryDisplay);
+}
+
+void HWComposerCallback::onRefreshReceived(int32_t sequenceId,
+ hwc2_display_t display)
+{
+ listener->on_refresh_received(listener, sequenceId, display);
+}
+
+struct hwc2_compat_device
+{
+ HWC2::Device *self;
+};
+
+struct hwc2_compat_display
+{
+ HWC2::Display *self;
+};
+
+struct hwc2_compat_layer
+{
+ HWC2::Layer *self;
+};
+
+struct hwc2_compat_out_fences
+{
+ std::unordered_map<HWC2::Layer*, android::sp<android::Fence>> fences;
+};
+
+hwc2_compat_device_t* hwc2_compat_device_new(bool useVrComposer)
+{
+ hwc2_compat_device_t *device = (hwc2_compat_device_t*) malloc(
+ sizeof(hwc2_compat_device_t));
+ if (!device)
+ return nullptr;
+
+ device->self = new HWC2::Device(useVrComposer);
+
+ return device;
+}
+
+void hwc2_compat_device_register_callback(hwc2_compat_device_t *device,
+ HWC2EventListener* listener,
+ int composerSequenceId)
+{
+ device->self->registerCallback(new HWComposerCallback(listener),
+ composerSequenceId);
+}
+
+void hwc2_compat_device_on_hotplug(hwc2_compat_device_t* device,
+ hwc2_display_t displayId, bool connected)
+{
+ device->self->onHotplug(displayId,
+ static_cast<HWC2::Connection>(connected));
+}
+
+hwc2_compat_display_t* hwc2_compat_device_get_display_by_id(
+ hwc2_compat_device_t *device, hwc2_display_t id)
+{
+ hwc2_compat_display_t *display = (hwc2_compat_display_t*) malloc(
+ sizeof(hwc2_compat_display_t));
+ if (!display)
+ return nullptr;
+
+ display->self = device->self->getDisplayById(id);
+
+ if (!display->self) {
+ free(display);
+ return nullptr;
+ }
+
+ return display;
+}
+
+HWC2DisplayConfig* hwc2_compat_display_get_active_config(
+ hwc2_compat_display_t* display)
+{
+ HWC2DisplayConfig* config = (HWC2DisplayConfig*) malloc(
+ sizeof(HWC2DisplayConfig));
+
+ std::shared_ptr<const HWC2::Display::Config> activeConfig;
+ auto error = display->self->getActiveConfig(&activeConfig);
+ if (error == HWC2::Error::BadConfig) {
+ fprintf(stderr, "getActiveConfig: No config active, returning null");
+ } else if (error != HWC2::Error::None) {
+ fprintf(stderr, "getActiveConfig failed for display %d: %s (%d)",
+ static_cast<int32_t>(display->self->getId()),
+ to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ } else if (!activeConfig) {
+ fprintf(stderr, "getActiveConfig returned empty config for display %d",
+ static_cast<int32_t>(display->self->getId()));
+ } else {
+ config->id = activeConfig->getId();
+ config->display = activeConfig->getDisplayId();
+ config->width = activeConfig->getWidth();
+ config->height = activeConfig->getHeight();
+ config->vsyncPeriod = activeConfig->getVsyncPeriod();
+ config->dpiX = activeConfig->getDpiX();
+ config->dpiY = activeConfig->getDpiY();
+
+ return config;
+ }
+
+ return nullptr;
+}
+
+hwc2_error_t hwc2_compat_display_accept_changes(hwc2_compat_display_t* display)
+{
+ HWC2::Error error = display->self->acceptChanges();
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_compat_layer_t* hwc2_compat_display_create_layer(hwc2_compat_display_t* display)
+{
+ hwc2_compat_layer_t *layer = (hwc2_compat_layer_t*) malloc(
+ sizeof(hwc2_compat_layer_t));
+ if (!layer)
+ return nullptr;
+
+ if (display->self->createLayer(&layer->self) != HWC2::Error::None)
+ return nullptr;
+
+ return layer;
+}
+
+void hwc2_compat_display_destroy_layer(hwc2_compat_display_t* display,
+ hwc2_compat_layer_t* layer)
+{
+ if (display->self->destroyLayer(layer->self) != HWC2::Error::None)
+ delete layer->self;
+
+ free(layer);
+}
+
+hwc2_error_t hwc2_compat_display_get_release_fences(hwc2_compat_display_t* display,
+ hwc2_compat_out_fences_t** outFences)
+{
+ hwc2_compat_out_fences_t *fences = new struct hwc2_compat_out_fences;
+
+ HWC2::Error error = display->self->getReleaseFences(&fences->fences);
+ if (error != HWC2::Error::None) {
+ delete fences;
+ } else {
+ *outFences = fences;
+ }
+
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_display_present(hwc2_compat_display_t* display,
+ int32_t* outPresentFence)
+{
+ android::sp<android::Fence> presentFence;
+ HWC2::Error error = display->self->present(&presentFence);
+
+ *outPresentFence = presentFence->dup();
+
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_display_set_client_target(hwc2_compat_display_t* display,
+ uint32_t slot,
+ struct ANativeWindowBuffer* buffer,
+ const int32_t acquireFenceFd,
+ android_dataspace_t dataspace)
+{
+ android::sp<android::GraphicBuffer> target(
+ new android::GraphicBuffer(buffer->handle,
+ android::GraphicBuffer::WRAP_HANDLE,
+ buffer->width, buffer->height,
+ buffer->format, /* layerCount */ 1,
+ buffer->usage, buffer->stride));
+
+ android::sp<android::Fence> acquireFence(
+ new android::Fence(acquireFenceFd));
+
+ HWC2::Error error = display->self->setClientTarget(0, target,
+ acquireFence, HAL_DATASPACE_UNKNOWN);
+
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_display_set_power_mode(hwc2_compat_display_t* display,
+ int mode)
+{
+ HWC2::Error error = display->self->setPowerMode(
+ static_cast<HWC2::PowerMode>(mode));
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_display_set_vsync_enabled(hwc2_compat_display_t* display,
+ int enabled)
+{
+ HWC2::Error error = display->self->setVsyncEnabled(
+ static_cast<HWC2::Vsync>(enabled));
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_display_validate(hwc2_compat_display_t* display,
+ uint32_t* outNumTypes,
+ uint32_t* outNumRequests)
+{
+ HWC2::Error error = display->self->validate(outNumTypes, outNumRequests);
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_buffer(hwc2_compat_layer_t* layer,
+ uint32_t slot,
+ struct ANativeWindowBuffer* buffer,
+ const int32_t acquireFenceFd)
+{
+ android::sp<android::GraphicBuffer> target(
+ new android::GraphicBuffer(buffer->handle,
+ android::GraphicBuffer::WRAP_HANDLE,
+ buffer->width, buffer->height,
+ buffer->format, /* layerCount */ 1,
+ buffer->usage, buffer->stride));
+
+ android::sp<android::Fence> acquireFence(
+ new android::Fence(acquireFenceFd));
+
+ HWC2::Error error = layer->self->setBuffer(0, target, acquireFence);
+
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_blend_mode(hwc2_compat_layer_t* layer, int mode)
+{
+ HWC2::Error error = layer->self->setBlendMode(
+ static_cast<HWC2::BlendMode>(mode));
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_color(hwc2_compat_layer_t* layer,
+ hwc_color_t color)
+{
+ HWC2::Error error = layer->self->setColor(color);
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_composition_type(hwc2_compat_layer_t* layer,
+ int type)
+{
+ HWC2::Error error = layer->self->setCompositionType(
+ static_cast<HWC2::Composition>(type));
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_dataspace(hwc2_compat_layer_t* layer,
+ android_dataspace_t dataspace)
+{
+ HWC2::Error error = layer->self->setDataspace(dataspace);
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_display_frame(hwc2_compat_layer_t* layer,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom)
+{
+ android::Rect r = {left, top, right, bottom};
+
+ HWC2::Error error = layer->self->setDisplayFrame(r);
+ return static_cast<hwc2_error_t>(error);
+}
+hwc2_error_t hwc2_compat_layer_set_plane_alpha(hwc2_compat_layer_t* layer,
+ float alpha)
+{
+ HWC2::Error error = layer->self->setPlaneAlpha(alpha);
+ return static_cast<hwc2_error_t>(error);
+}
+hwc2_error_t hwc2_compat_layer_set_sideband_stream(hwc2_compat_layer_t* layer,
+ const native_handle_t* stream)
+{
+ HWC2::Error error = layer->self->setSidebandStream(stream);
+ return static_cast<hwc2_error_t>(error);
+}
+hwc2_error_t hwc2_compat_layer_set_source_crop(hwc2_compat_layer_t* layer,
+ float left, float top,
+ float right, float bottom)
+{
+ android::FloatRect r = {left, top, right, bottom};
+
+ HWC2::Error error = layer->self->setSourceCrop(r);
+ return static_cast<hwc2_error_t>(error);
+}
+hwc2_error_t hwc2_compat_layer_set_transform(hwc2_compat_layer_t* layer,
+ int transform)
+{
+ HWC2::Error error = layer->self->setTransform(
+ static_cast<HWC2::Transform>(transform));
+ return static_cast<hwc2_error_t>(error);
+}
+
+hwc2_error_t hwc2_compat_layer_set_visible_region(hwc2_compat_layer_t* layer,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom)
+{
+ android::Rect r = {left, top, right, bottom};
+
+ HWC2::Error error = layer->self->setVisibleRegion(android::Region(r));
+ return static_cast<hwc2_error_t>(error);
+}
+
+int32_t hwc2_compat_out_fences_get_fence(hwc2_compat_out_fences_t* fences,
+ hwc2_compat_layer_t* layer)
+{
+ auto iter = fences->fences.find(layer->self);
+
+ if(iter != fences->fences.end()) {
+ return iter->second->dup();
+ } else {
+ return -1;
+ }
+}
+
+void hwc2_compat_out_fences_destroy(hwc2_compat_out_fences_t* fences)
+{
+ delete fences;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/hwc2_compatibility_layer.h
^
|
+(symlink to ../../../libhybris/hybris/include/hybris/hwc2/hwc2_compatibility_layer.h)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/hybris/grallocusage/GrallocUsageConversion.h
^
|
+(symlink to ../../../../../libhybris/hybris/include/hybris/grallocusage/GrallocUsageConversion.h)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/direct_hwc2_test.cpp
^
|
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2018 TheKit <nekit1000@gmail.com>
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+#include <mutex>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <cutils/log.h>
+#include <sync/sync.h>
+
+#include "hybris-gralloc.h"
+#include <hwcomposer_window.h>
+
+#include "hwc2_compatibility_layer.h"
+
+const char vertex_src [] =
+" \
+ attribute vec4 position; \
+ varying mediump vec2 pos; \
+ uniform vec4 offset; \
+ \
+ void main() \
+ { \
+ gl_Position = position + offset; \
+ pos = position.xy; \
+ } \
+";
+
+
+const char fragment_src [] =
+" \
+ varying mediump vec2 pos; \
+ uniform mediump float phase; \
+ \
+ void main() \
+ { \
+ gl_FragColor = vec4( 1., 0.9, 0.7, 1.0 ) * \
+ cos( 30.*sqrt(pos.x*pos.x + 1.5*pos.y*pos.y) \
+ + atan(pos.y,pos.x) - phase ); \
+ } \
+";
+
+GLuint load_shader(const char *shader_source, GLenum type)
+{
+ GLuint shader = glCreateShader(type);
+
+ glShaderSource(shader, 1, &shader_source, NULL);
+ glCompileShader(shader);
+
+ return shader;
+}
+
+
+GLfloat norm_x = 0.0;
+GLfloat norm_y = 0.0;
+GLfloat offset_x = 0.0;
+GLfloat offset_y = 0.0;
+GLfloat p1_pos_x = 0.0;
+GLfloat p1_pos_y = 0.0;
+
+GLint phase_loc;
+GLint offset_loc;
+GLint position_loc;
+
+const float vertexArray[] = {
+ 0.0, 1.0, 0.0,
+ -1., 0.0, 0.0,
+ 0.0, -1.0, 0.0,
+ 1., 0.0, 0.0,
+ 0.0, 1., 0.0
+};
+
+std::mutex hotplugMutex;
+std::condition_variable hotplugCv;
+hwc2_compat_device_t* hwcDevice;
+
+class HWComposer : public HWComposerNativeWindow
+{
+ private:
+ hwc2_compat_layer_t *layer;
+ hwc2_compat_display_t *hwcDisplay;
+ int lastPresentFence = -1;
+ protected:
+ void present(HWComposerNativeWindowBuffer *buffer);
+
+ public:
+
+ HWComposer(unsigned int width, unsigned int height, unsigned int format,
+ hwc2_compat_display_t *display, hwc2_compat_layer_t *layer);
+ void set();
+};
+
+HWComposer::HWComposer(unsigned int width, unsigned int height,
+ unsigned int format, hwc2_compat_display_t* display,
+ hwc2_compat_layer_t *layer) :
+ HWComposerNativeWindow(width, height, format)
+{
+ this->layer = layer;
+ this->hwcDisplay = display;
+}
+
+void HWComposer::present(HWComposerNativeWindowBuffer *buffer)
+{
+ uint32_t numTypes = 0;
+ uint32_t numRequests = 0;
+ hwc2_display_t displayId = 0;
+
+ hwc2_error_t error = hwc2_compat_display_validate(hwcDisplay, &numTypes,
+ &numRequests);
+
+ if (error != HWC2_ERROR_NONE && error != HWC2_ERROR_HAS_CHANGES) {
+ ALOGE("prepare: validate failed for display %d: %s (%d)",
+ (uint32_t) displayId,
+ to_string(static_cast<HWC2::Error>(error)).c_str(), error);
+ return;
+ }
+
+ if (numTypes || numRequests) {
+ ALOGE("prepare: validate required changes for display %d: %s (%d)",
+ (uint32_t) displayId,
+ to_string(static_cast<HWC2::Error>(error)).c_str(), error);
+ return;
+ }
+
+ error = hwc2_compat_display_accept_changes(hwcDisplay);
+ if (error != HWC2_ERROR_NONE) {
+ ALOGE("prepare: acceptChanges failed: %s",
+ to_string(static_cast<HWC2::Error>(error)).c_str());
+ return;
+ }
+
+ hwc2_compat_display_set_client_target(hwcDisplay, /* slot */0, buffer,
+ getFenceBufferFd(buffer),
+ HAL_DATASPACE_UNKNOWN);
+
+ int presentFence;
+ hwc2_compat_display_present(hwcDisplay, &presentFence);
+
+ if (error != HWC2_ERROR_NONE) {
+ ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
+ (uint32_t) displayId,
+ to_string(static_cast<HWC2::Error>(error)).c_str(), error);
+ return;
+ }
+
+ hwc2_compat_out_fences_t* fences;
+ error = hwc2_compat_display_get_release_fences(
+ hwcDisplay, &fences);
+
+ if (error != HWC2_ERROR_NONE) {
+ ALOGE("presentAndGetReleaseFences: Failed to get release fences "
+ "for display %d: %s (%d)",
+ (uint32_t) displayId, to_string(static_cast<HWC2::Error>(error)).c_str(),
+ error);
+ return;
+ }
+
+ int fenceFd = hwc2_compat_out_fences_get_fence(fences, layer);
+ if (fenceFd != -1)
+ setFenceBufferFd(buffer, fenceFd);
+
+ hwc2_compat_out_fences_destroy(fences);
+
+ if (lastPresentFence != -1) {
+ sync_wait(lastPresentFence, -1);
+ close(lastPresentFence);
+ }
+ lastPresentFence = presentFence;
+}
+
+void onVsyncReceived(HWC2EventListener* listener, int32_t sequenceId,
+ hwc2_display_t display, int64_t timestamp)
+{
+}
+
+void onHotplugReceived(HWC2EventListener* listener, int32_t sequenceId,
+ hwc2_display_t display, bool connected,
+ bool primaryDisplay)
+{
+ ALOGI("onHotplugReceived(%d, %" PRIu64 ", %s, %s)",
+ sequenceId, display,
+ connected ?
+ "connected" : "disconnected",
+ primaryDisplay ? "primary" : "external");
+
+ {
+ std::lock_guard<std::mutex> lock(hotplugMutex);
+ hwc2_compat_device_on_hotplug(hwcDevice, display, connected);
+ }
+
+ hotplugCv.notify_all();
+}
+
+void onRefreshReceived(HWC2EventListener* listener,
+ int32_t sequenceId, hwc2_display_t display)
+{
+}
+
+HWC2EventListener eventListener = {
+ &onVsyncReceived,
+ &onHotplugReceived,
+ &onRefreshReceived
+};
+
+int main()
+{
+ EGLDisplay display;
+ EGLConfig ecfg;
+ EGLint num_config;
+ EGLint attr[] = { // some attributes to set up our egl-interface
+ EGL_BUFFER_SIZE, 32,
+ EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+ EGLSurface surface;
+ EGLint ctxattr[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ EGLContext context;
+
+ EGLBoolean rv;
+
+ int err;
+ int composerSequenceId = 0;
+
+ hwcDevice = hwc2_compat_device_new(false);
+ assert(hwcDevice);
+
+ hwc2_compat_device_register_callback(hwcDevice, &eventListener,
+ composerSequenceId);
+
+ std::unique_lock<std::mutex> lock(hotplugMutex);
+ hwc2_compat_display_t* hwcDisplay;
+ while (!(hwcDisplay = hwc2_compat_device_get_display_by_id(hwcDevice, 0))) {
+ /* Wait at most 5s for hotplug events */
+ hotplugCv.wait_for(lock, std::chrono::seconds(5));
+ }
+ hotplugMutex.unlock();
+ assert(hwcDisplay);
+
+ hwc2_compat_display_set_power_mode(hwcDisplay, HWC2_POWER_MODE_ON);
+
+ std::shared_ptr<HWC2DisplayConfig> config = {
+ hwc2_compat_display_get_active_config(hwcDisplay), free };
+
+ printf("width: %i height: %i\n", config->width, config->height);
+
+ hwc2_compat_layer_t* layer = hwc2_compat_display_create_layer(hwcDisplay);
+
+ hwc2_compat_layer_set_composition_type(layer, HWC2_COMPOSITION_CLIENT);
+ hwc2_compat_layer_set_blend_mode(layer, HWC2_BLEND_MODE_NONE);
+ hwc2_compat_layer_set_source_crop(layer, 0.0f, 0.0f, config->width,
+ config->height);
+ hwc2_compat_layer_set_display_frame(layer, 0, 0, config->width,
+ config->height);
+ hwc2_compat_layer_set_visible_region(layer, 0, 0, config->width,
+ config->height);
+
+ HWComposer *win = new HWComposer(config->width, config->height,
+ HAL_PIXEL_FORMAT_RGBA_8888, hwcDisplay,
+ layer);
+ printf("created native window\n");
+ hybris_gralloc_initialize(0);
+
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(display != EGL_NO_DISPLAY);
+
+ rv = eglInitialize(display, 0, 0);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(rv == EGL_TRUE);
+
+ eglChooseConfig((EGLDisplay) display, attr, &ecfg, 1, &num_config);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(rv == EGL_TRUE);
+
+ surface = eglCreateWindowSurface((EGLDisplay) display, ecfg,
+ (EGLNativeWindowType) static_cast<ANativeWindow *> (win), NULL);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(surface != EGL_NO_SURFACE);
+
+ context = eglCreateContext((EGLDisplay) display, ecfg, EGL_NO_CONTEXT,
+ ctxattr);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(context != EGL_NO_CONTEXT);
+
+ assert(eglMakeCurrent((EGLDisplay) display, surface, surface,
+ context) == EGL_TRUE);
+
+ const char *version = (const char *)glGetString(GL_VERSION);
+ assert(version);
+ printf("%s\n",version);
+
+ GLuint vertexShader = load_shader (vertex_src, GL_VERTEX_SHADER);
+ GLuint fragmentShader = load_shader(fragment_src, GL_FRAGMENT_SHADER);
+
+ GLuint shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, vertexShader);
+ glAttachShader(shaderProgram, fragmentShader);
+
+ glLinkProgram(shaderProgram);
+ glUseProgram(shaderProgram);
+
+ position_loc = glGetAttribLocation(shaderProgram, "position");
+ phase_loc = glGetUniformLocation(shaderProgram, "phase");
+ offset_loc = glGetUniformLocation(shaderProgram, "offset");
+
+ if (position_loc < 0 || phase_loc < 0 || offset_loc < 0) {
+ return 1;
+ }
+
+ glClearColor (1., 1., 1., 1.); // background color
+ float phase = 0;
+ int i, oldretire = -1, oldrelease = -1, oldrelease2 = -1;
+ for (i=0; i<60*60; ++i) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUniform1f (phase_loc, phase);
+ phase = fmodf (phase + 0.5f, 2.f * 3.141f);
+
+ glUniform4f(offset_loc, offset_x, offset_y, 0.0, 0.0);
+
+ glVertexAttribPointer(position_loc, 3, GL_FLOAT,
+ GL_FALSE, 0, vertexArray);
+ glEnableVertexAttribArray (position_loc);
+ glDrawArrays (GL_TRIANGLE_STRIP, 0, 5);
+
+ eglSwapBuffers ((EGLDisplay) display, surface);
+ }
+
+ printf("stop\n");
+
+ return 0;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/hwcomposer.h
^
|
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 Jolla Ltd
+ *
+ * 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.
+ */
+
+#ifndef HYBRIS_HWCOMPOSER_H
+#define HYBRIS_HWCOMPOSER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ANativeWindow;
+struct ANativeWindowBuffer;
+
+typedef void (*HWCPresentCallback)(void *user_data, struct ANativeWindow *window,
+ struct ANativeWindowBuffer *buffer);
+
+/** Create a new HWC ANativeWindow.
+ *
+ * The Window can be casted to EGLNativeWindowType and used to create
+ * an EGLSurface.
+ * The specified present callback will be called by the window when a new
+ * buffer is ready to be presented on screen. It is responsibility of the
+ * caller to make sure that happens, by using the hwcomposer API.
+ * Returns the window on success or NULL on failure.
+ *
+ * \param width The width of the window in pixels.
+ * \param height The height of the window in pixels.
+ * \param format The HAL format of the window.
+ * \param present The present callback the window will use.
+ * \param cbData The callback data the window will pass along to the present callback.
+ *
+ * \sa HWCNativeWindowDestroy
+ */
+struct ANativeWindow *HWCNativeWindowCreate(unsigned int width, unsigned int height, unsigned int format,
+ HWCPresentCallback present, void *cbData);
+
+/** Destroy a HWC ANativeWindow.
+ *
+ * Destroys a native window created with HWCNativeWindowCreate().
+ * It is not necessary to call this after using eglDestroyWindowSurface()
+ * with an EGLSurface backing a valid ANativeWindow, the window will
+ * be destroyed automatically.
+ *
+ * \sa HWCNativeWindowCreate
+ */
+void HWCNativeWindowDestroy(struct ANativeWindow *window);
+
+/** Get the current fence FD on a buffer.
+ *
+ * The buffer must be a buffer passed from the HWC layer trough the present
+ * callback of a ANativeWindow.
+ *
+ * \sa HWCNativeWindowCreate
+ * \sa HWCNativeBufferSetFence
+ */
+int HWCNativeBufferGetFence(struct ANativeWindowBuffer *buf);
+
+/** Set the current fence FD on a buffer.
+ *
+ * The buffer must be a buffer passed from the HWC layer trough the present
+ * callback of a ANativeWindow.
+ *
+ * \sa HWCNativeWindowCreate
+ * \sa HWCNativeBufferGetFence
+ */
+void HWCNativeBufferSetFence(struct ANativeWindowBuffer *buf, int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/hwcomposer_window.cpp
^
|
+(symlink to ../../../../libhybris/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/hwcomposer_window.h
^
|
+(symlink to ../../../../libhybris/hybris/egl/platforms/hwcomposer/hwcomposer_window.h)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/hybris-gralloc.c
^
|
+(symlink to ../../../hybris/gralloc/gralloc.c)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/hybris-gralloc.h
^
|
+(symlink to ../../../hybris/include/hybris/gralloc/gralloc.h)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/nativewindowbase.cpp
^
|
+(symlink to ../../../../libhybris/hybris/egl/platforms/common/nativewindowbase.cpp)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/nativewindowbase.h
^
|
+(symlink to ../../../../libhybris/hybris/egl/platforms/common/nativewindowbase.h)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/hwc2/tests/support.h
^
|
@@ -0,0 +1,17 @@
+#ifndef SUPPORT_H_
+#define SUPPORT_H_
+
+#include <stddef.h>
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/input/Android.mk
^
|
@@ -62,9 +62,8 @@
LOCAL_C_INCLUDES := \
$(HYBRIS_PATH)/include \
bionic \
- bionic/libstdc++/include \
+ external/libcxx/include \
external/gtest/include \
- external/stlport/stlport \
external/skia/include/core
LOCAL_SHARED_LIBRARIES := \
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/input/input_compatibility_layer.cpp
^
|
@@ -67,13 +67,13 @@
ct,
SkAlphaType::kPremul_SkAlphaType),
0);
-#elif ANDROID_VERSION_MAJOR==6
-bitmap.setInfo(
- SkImageInfo::Make(bitmap_width,
- bitmap_height,
- kRGBA_8888_SkColorType,
- SkAlphaType::kPremul_SkAlphaType),
- 0);
+#elif ANDROID_VERSION_MAJOR>=6
+ bitmap.setInfo(
+ SkImageInfo::Make(bitmap_width,
+ bitmap_height,
+ kRGBA_8888_SkColorType,
+ SkAlphaType::kPremul_SkAlphaType),
+ 0);
#endif
bitmap.allocPixels();
@@ -107,6 +107,17 @@
outResources->spotAnchor = spotAnchorIcon.copy();
}
+#if ANDROID_VERSION_MAJOR >= 7
+ void loadPointerIcon(android::SpriteIcon*)
+ {
+ }
+
+ void loadAdditionalMouseResources(std::map<int32_t, android::SpriteIcon>* /*coutResources*/,
+ std::map<int32_t, android::PointerAnimation>* /*outAnimationResources*/) {}
+ int32_t getDefaultPointerIconId() { return 0; }
+ int32_t getCustomPointerIconId() { return 0; }
+#endif
+
android::SpriteIcon spotHoverIcon;
android::SpriteIcon spotTouchIcon;
android::SpriteIcon spotAnchorIcon;
@@ -365,14 +376,24 @@
void android_input_stack_start()
{
+#if ANDROID_VERSION_MAJOR >= 7
+ global_state->input_reader_thread->run("input");
+ global_state->looper_thread->run("loop");
+#else
global_state->input_reader_thread->run();
global_state->looper_thread->run();
+#endif
}
void android_input_stack_start_waiting_for_flag(bool* flag)
{
+#if ANDROID_VERSION_MAJOR >= 7
+ global_state->input_reader_thread->run("input");
+ global_state->looper_thread->run("loop");
+#else
global_state->input_reader_thread->run();
global_state->looper_thread->run();
+#endif
while (!*flag) {
global_state->wait_condition.waitRelative(
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/Android.mk
^
|
@@ -1,12 +1,24 @@
LOCAL_PATH:= $(call my-dir)
+
+HYBRIS_MEDIA_32_BIT_ONLY := $(shell cat frameworks/av/media/libmediaplayerservice/Android.mk |grep LOCAL_32_BIT_ONLY |grep -o "true\|false")
+
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+HYBRIS_MEDIA_MULTILIB := 32
+endif
+
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../Android.common.mk
+ifeq ($(CAMERA_SERVICE_WANT_UBUNTU_HEADERS),1)
+ LOCAL_CPPFLAGS += -DWANT_UBUNTU_CAMERA_HEADERS
+endif
+
LOCAL_SRC_FILES := \
camera_service.cpp
LOCAL_SHARED_LIBRARIES := \
libcameraservice \
+ libcamera_client \
libmedialogservice \
libcutils \
libmedia \
@@ -40,6 +52,11 @@
LOCAL_MODULE_STEM_64 := $(if $(filter false,$(BOARD_UBUNTU_PREFER_32_BIT)),$(LOCAL_MODULE),$(LOCAL_MODULE)_64)
endif
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := 32
+endif
+
include $(BUILD_EXECUTABLE)
# -------------------------------------------------
@@ -108,6 +125,7 @@
frameworks/av/media/libstagefright/include \
frameworks/av/include \
frameworks/native/include \
+ frameworks/native/include/media/hardware \
system/media/audio_utils/include \
frameworks/av/services/camera/libcameraservice
@@ -129,6 +147,11 @@
$(TOP)/$(MTK_PATH_SOURCE)/frameworks/av/include
endif
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := 32
+endif
+
include $(BUILD_SHARED_LIBRARY)
# -------------------------------------------------
@@ -145,9 +168,8 @@
LOCAL_C_INCLUDES := \
$(HYBRIS_PATH)/include \
bionic \
- bionic/libstdc++/include \
+ external/libcxx/include \
external/gtest/include \
- external/stlport/stlport \
external/skia/include/core \
frameworks/base/include
@@ -170,4 +192,9 @@
LOCAL_MODULE_STEM_64 := $(if $(filter false,$(BOARD_UBUNTU_PREFER_32_BIT)),$(LOCAL_MODULE),$(LOCAL_MODULE)_64)
endif
+ifeq ($(HYBRIS_MEDIA_32_BIT_ONLY),true)
+LOCAL_32_BIT_ONLY := true
+LOCAL_MULTILIB := 32
+endif
+
include $(BUILD_EXECUTABLE)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/camera_service.cpp
^
|
@@ -23,7 +23,10 @@
#include "media_recorder_factory.h"
#include "media_recorder.h"
+#if ANDROID_VERSION_MAJOR==5 && WANT_UBUNTU_CAMERA_HEADERS
#include <media/camera_record_service.h>
+#endif
+
#include <CameraService.h>
#include <signal.h>
@@ -45,7 +48,9 @@
// for creating a new IMediaRecorder (MediaRecorder) instance over Binder
MediaRecorderFactory::instantiate();
// Enable audio recording for camera recording
+#if ANDROID_VERSION_MAJOR==5 && WANT_UBUNTU_CAMERA_HEADERS
CameraRecordService::instantiate();
+#endif
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/decoding_service.cpp
^
|
@@ -38,7 +38,9 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/Surface.h>
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
#include <gui/NativeBufferAlloc.h>
+#endif
namespace android {
@@ -290,7 +292,9 @@
buffer_queue = new BufferQueue(NULL);
ALOGD("buffer_queue: %p", (void*)buffer_queue.get());
#endif
-#if ANDROID_VERSION_MAJOR>=5
+#if ANDROID_VERSION_MAJOR>=7
+ producer->setMaxDequeuedBufferCount(5);
+#elif ANDROID_VERSION_MAJOR>=5
producer->setBufferCount(5);
#else
buffer_queue->setBufferCount(5);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_codec_source_layer.cpp
^
|
@@ -351,11 +351,16 @@
bool media_codec_source_request_idr_frame(MediaCodecSourceWrapper *source)
{
+#if ANDROID_VERSION_MAJOR < 7
MediaCodecSourcePrivate *d = MediaCodecSourcePrivate::toPrivate(source);
if (!d || !d->codec.get())
return false;
android::status_t err = d->codec->requestIDRFrame();
+#else
+ // requestIDRFrame is done in start
+ android::status_t err = android::OK;
+#endif
if (err != android::OK)
return false;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_compatibility_layer.cpp
^
|
@@ -44,10 +44,13 @@
#include <utils/Log.h>
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
#include <gui/NativeBufferAlloc.h>
+#endif
#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__)
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
namespace android
{
NativeBufferAlloc::NativeBufferAlloc() {
@@ -73,6 +76,8 @@
return graphicBuffer;
}
}
+#endif
+
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
struct FrameAvailableListener : public android::SurfaceTexture::FrameAvailableListener
#else
@@ -254,8 +259,10 @@
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
surfaceTexture->getBufferQueue()->setBufferCount(5);
-#else
+#elif ANDROID_VERSION_MAJOR<7
bq->setBufferCount(5);
+#else
+ bq->setMaxDequeuedBufferCount(5);
#endif
texture = surfaceTexture;
texture->setFrameAvailableListener(frame_listener);
@@ -488,15 +495,16 @@
return BAD_VALUE;
}
- android::sp<android::NativeBufferAlloc> native_alloc(
- new android::NativeBufferAlloc()
- );
-
#if ANDROID_VERSION_MAJOR>=5
android::sp<IGraphicBufferProducer> producer;
android::sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
#else
+#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
+ android::sp<android::NativeBufferAlloc> native_alloc(
+ new android::NativeBufferAlloc()
+ );
+#endif
android::sp<android::BufferQueue> buffer_queue(
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=3
new android::BufferQueue(false, NULL, native_alloc)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_recorder.cpp
^
|
@@ -24,16 +24,23 @@
#include "media_recorder_factory.h"
#include <utils/Log.h>
+#if ANDROID_VERSION_MAJOR >= 7
+#include <camera/android/hardware/ICamera.h>
+#endif
#include <binder/IServiceManager.h>
#include <utils/String8.h>
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
#include <gui/IGraphicBufferProducer.h>
+namespace a = android;
+namespace ah = android::hardware;
-namespace android {
-
-status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
+#if ANDROID_VERSION_MAJOR >= 7
+a::status_t a::MediaRecorder::setCamera(const sp<ah::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
+#else
+a::status_t a::MediaRecorder::setCamera(const sp<a::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
+#endif
{
ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
if (mMediaRecorder == NULL) {
@@ -54,7 +61,7 @@
return ret;
}
-status_t MediaRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
+a::status_t a::MediaRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
{
ALOGV("setPreviewSurface(%p)", surface.get());
if (mMediaRecorder == NULL) {
@@ -79,7 +86,7 @@
return ret;
}
-status_t MediaRecorder::init()
+a::status_t a::MediaRecorder::init()
{
ALOGV("init");
if (mMediaRecorder == NULL) {
@@ -109,7 +116,7 @@
return ret;
}
-status_t MediaRecorder::setVideoSource(int vs)
+a::status_t a::MediaRecorder::setVideoSource(int vs)
{
ALOGV("setVideoSource(%d)", vs);
if (mMediaRecorder == NULL) {
@@ -144,7 +151,7 @@
return ret;
}
-status_t MediaRecorder::setAudioSource(int as)
+a::status_t a::MediaRecorder::setAudioSource(int as)
{
ALOGV("setAudioSource(%d)", as);
if (mMediaRecorder == NULL) {
@@ -177,7 +184,7 @@
return ret;
}
-status_t MediaRecorder::setOutputFormat(int of)
+a::status_t a::MediaRecorder::setOutputFormat(int of)
{
ALOGV("setOutputFormat(%d)", of);
if (mMediaRecorder == NULL) {
@@ -203,7 +210,7 @@
return ret;
}
-status_t MediaRecorder::setVideoEncoder(int ve)
+a::status_t a::MediaRecorder::setVideoEncoder(int ve)
{
ALOGV("setVideoEncoder(%d)", ve);
if (mMediaRecorder == NULL) {
@@ -233,7 +240,7 @@
return ret;
}
-status_t MediaRecorder::setAudioEncoder(int ae)
+a::status_t a::MediaRecorder::setAudioEncoder(int ae)
{
ALOGV("setAudioEncoder(%d)", ae);
if (mMediaRecorder == NULL) {
@@ -263,7 +270,7 @@
return ret;
}
#if ANDROID_VERSION_MAJOR<=5
-status_t MediaRecorder::setOutputFile(const char* path)
+a::status_t a::MediaRecorder::setOutputFile(const char* path)
{
ALOGV("setOutputFile(%s)", path);
if (mMediaRecorder == NULL) {
@@ -290,7 +297,7 @@
}
#endif
-status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
+a::status_t a::MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
{
ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
if (mMediaRecorder == NULL) {
@@ -327,7 +334,7 @@
return ret;
}
-status_t MediaRecorder::setVideoSize(int width, int height)
+a::status_t a::MediaRecorder::setVideoSize(int width, int height)
{
ALOGV("setVideoSize(%d, %d)", width, height);
if (mMediaRecorder == NULL) {
@@ -356,7 +363,7 @@
// Query a SurfaceMediaSurface through the Mediaserver, over the
// binder interface. This is used by the Filter Framework (MediaEncoder)
// to get an <IGraphicBufferProducer> object to hook up to ANativeWindow.
-sp<IGraphicBufferProducer> MediaRecorder::
+a::sp<a::IGraphicBufferProducer> a::MediaRecorder::
querySurfaceMediaSourceFromMediaServer()
{
Mutex::Autolock _l(mLock);
@@ -368,7 +375,7 @@
return mSurfaceMediaSource;
}
-status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
+a::status_t a::MediaRecorder::setVideoFrameRate(int frames_per_second)
{
ALOGV("setVideoFrameRate(%d)", frames_per_second);
if (mMediaRecorder == NULL) {
@@ -393,7 +400,7 @@
return ret;
}
-status_t MediaRecorder::setParameters(const String8& params) {
+a::status_t a::MediaRecorder::setParameters(const String8& params) {
ALOGV("setParameters(%s)", params.string());
if (mMediaRecorder == NULL) {
ALOGE("media recorder is not initialized yet");
@@ -420,7 +427,7 @@
return ret;
}
-status_t MediaRecorder::prepare()
+a::status_t a::MediaRecorder::prepare()
{
ALOGV("prepare");
if (mMediaRecorder == NULL) {
@@ -459,7 +466,7 @@
return ret;
}
-status_t MediaRecorder::getMaxAmplitude(int* max)
+a::status_t a::MediaRecorder::getMaxAmplitude(int* max)
{
ALOGV("getMaxAmplitude");
if (mMediaRecorder == NULL) {
@@ -480,7 +487,7 @@
return ret;
}
-status_t MediaRecorder::start()
+a::status_t a::MediaRecorder::start()
{
ALOGV("start");
if (mMediaRecorder == NULL) {
@@ -502,7 +509,7 @@
return ret;
}
-status_t MediaRecorder::stop()
+a::status_t a::MediaRecorder::stop()
{
ALOGV("stop");
if (mMediaRecorder == NULL) {
@@ -530,7 +537,7 @@
}
// Reset should be OK in any state
-status_t MediaRecorder::reset()
+a::status_t a::MediaRecorder::reset()
{
ALOGV("reset");
if (mMediaRecorder == NULL) {
@@ -566,7 +573,7 @@
return ret;
}
-status_t MediaRecorder::close()
+a::status_t a::MediaRecorder::close()
{
ALOGV("close");
if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
@@ -584,7 +591,7 @@
return ret;
}
-status_t MediaRecorder::doReset()
+a::status_t a::MediaRecorder::doReset()
{
ALOGV("doReset");
status_t ret = mMediaRecorder->reset();
@@ -598,7 +605,7 @@
return ret;
}
-void MediaRecorder::doCleanUp()
+void a::MediaRecorder::doCleanUp()
{
ALOGV("doCleanUp");
mIsAudioSourceSet = false;
@@ -609,7 +616,7 @@
}
// Release should be OK in any state
-status_t MediaRecorder::release()
+a::status_t a::MediaRecorder::release()
{
ALOGV("release");
if (mMediaRecorder != NULL) {
@@ -619,7 +626,7 @@
}
-MediaRecorder::MediaRecorder()
+a::MediaRecorder::MediaRecorder()
: mMediaRecorderFactory(NULL),
mSurfaceMediaSource(NULL)
{
@@ -650,12 +657,12 @@
doCleanUp();
}
-status_t MediaRecorder::initCheck()
+a::status_t a::MediaRecorder::initCheck()
{
return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
}
-MediaRecorder::~MediaRecorder()
+a::MediaRecorder::~MediaRecorder()
{
ALOGV("destructor");
if (mMediaRecorder != NULL) {
@@ -667,7 +674,7 @@
}
}
-status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
+a::status_t a::MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
{
ALOGV("setListener");
Mutex::Autolock _l(mLock);
@@ -683,7 +690,7 @@
return NO_ERROR;
}
-status_t MediaRecorder::setClientName(const String16& clientName)
+a::status_t a::MediaRecorder::setClientName(const String16& clientName)
{
ALOGV("setClientName");
if (mMediaRecorder == NULL) {
@@ -704,7 +711,7 @@
return NO_ERROR;
}
-void MediaRecorder::notify(int msg, int ext1, int ext2)
+void a::MediaRecorder::notify(int msg, int ext1, int ext2)
{
ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
@@ -721,7 +728,7 @@
}
}
-void MediaRecorder::readAudio()
+void a::MediaRecorder::readAudio()
{
ALOGV("%s", __PRETTY_FUNCTION__);
@@ -739,10 +746,8 @@
}
}
-void MediaRecorder::died()
+void a::MediaRecorder::died()
{
ALOGV("died");
notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
}
-
-} // namespace android
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_recorder.h
^
|
@@ -34,7 +34,13 @@
class Surface;
class IMediaRecorder;
class IMediaRecorderFactory;
+#if ANDROID_VERSION_MAJOR >= 7
+namespace hardware {
class ICamera;
+}
+#else
+class ICamera;
+#endif
class ICameraRecordingProxy;
class IGraphicBufferProducer;
class Surface;
@@ -214,7 +220,11 @@
void died();
status_t initCheck();
+#if ANDROID_VERSION_MAJOR>=7
+ status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
+#else
status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
+#endif
status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
status_t setVideoSource(int vs);
status_t setAudioSource(int as);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_recorder_client.cpp
^
|
@@ -52,9 +52,13 @@
REPORT_FUNCTION();
release();
}
-
+#if ANDROID_VERSION_MAJOR >= 7
+status_t MediaRecorderClient::setCamera(const sp<android::hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy)
+#else
status_t MediaRecorderClient::setCamera(const sp<android::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy)
+#endif
{
REPORT_FUNCTION();
Mutex::Autolock lock(recorder_lock);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_recorder_client.h
^
|
@@ -32,6 +32,13 @@
class Mutex;
class BpMediaRecorderObserver;
+#if ANDROID_VERSION_MAJOR >= 7
+namespace hardware {
+class ICamera;
+}
+#else
+class ICamera;
+#endif
/*!
* \brief The MediaRecorderClient struct wraps the service side of the MediaRecorder class
*/
@@ -41,8 +48,13 @@
MediaRecorderClient();
virtual ~MediaRecorderClient();
+#if ANDROID_VERSION_MAJOR>=7
+ virtual status_t setCamera(const sp<android::hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy);
+#else
virtual status_t setCamera(const sp<ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy);
+#endif
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
virtual status_t setVideoSource(int vs);
virtual status_t setAudioSource(int as);
@@ -64,10 +76,10 @@
virtual status_t getMaxAmplitude(int* max);
virtual status_t start();
virtual status_t stop();
-#ifdef BOARD_HAS_MEDIA_RECORDER_PAUSE
+#if defined(BOARD_HAS_MEDIA_RECORDER_PAUSE) || ANDROID_VERSION_MAJOR>=7
virtual status_t pause();
#endif
-#ifdef BOARD_HAS_MEDIA_RECORDER_RESUME
+#if defined(BOARD_HAS_MEDIA_RECORDER_RESUME) || ANDROID_VERSION_MAJOR>=7
virtual status_t resume();
#endif
virtual status_t reset();
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/media/media_recorder_layer.cpp
^
|
@@ -26,6 +26,9 @@
#include <hybris/internal/camera_control.h>
#include <hybris/media/media_recorder_layer.h>
+#if ANDROID_MAJOR_VERSION >= 7
+#include "camera/android/hardware/ICamera.h"
+#endif
#include <utils/KeyedVector.h>
#include <utils/Log.h>
@@ -230,7 +233,6 @@
}
mr->init();
-
return mr->setCamera(control->camera->remote(), control->camera->getRecordingProxy());
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/compat/surface_flinger/direct_sf_test.cpp
^
|
@@ -21,6 +21,7 @@
#include <cstdio>
#include <unistd.h>
+#include <stdlib.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/Makefile.am
^
|
@@ -1,4 +1,4 @@
-SUBDIRS = include properties common hardware
+SUBDIRS = include common properties hardware gralloc
if HAS_ANDROID_4_2_0
SUBDIRS += libsync
@@ -6,13 +6,11 @@
if HAS_ANDROID_5_0_0
SUBDIRS += libsync
endif
-SUBDIRS += egl glesv1 glesv2 ui sf input camera vibrator media wifi opencl
+SUBDIRS += egl glesv1 glesv2 ui sf input camera vibrator media opencl wifi hwc2
-if HAS_LIBNFC_NXP_HEADERS
SUBDIRS += libnfc_nxp libnfc_ndef_nxp
-endif
-SUBDIRS += utils tests
+SUBDIRS += utils tests
MAINTAINERCLEANFILES = \
aclocal.m4 compile config.guess config.sub \
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/Makefile.am
^
|
@@ -15,14 +15,27 @@
SUBDIRS += n
endif
+if HAS_ANDROID_8_0_0
+SUBDIRS += o
+endif
+
libhybris_common_la_SOURCES = \
hooks.c \
hooks_shm.c \
strlcpy.c \
strlcat.c \
logging.c \
- sysconf.c
+ sysconf.c \
+ legacy_properties/properties.c \
+ legacy_properties/cache.c
+if WANT_RUNTIME_PROPERTY_CACHE
+libhybris_common_la_SOURCES += \
+ legacy_properties/runtime_cache.c
+libhybris_common_la_CFLAGS =
+else
+libhybris_common_la_CFLAGS = -DNO_RUNTIME_PROPERTY_CACHE
+endif
if WANT_ARM_TRACING
libhybris_common_la_SOURCES += \
wrappers.c \
@@ -41,7 +54,7 @@
if WANT_ARM_TRACING
# thumb mode not supported
-libhybris_common_la_CFLAGS = \
+libhybris_common_la_CFLAGS += \
-marm
libhybris_common_la_CPPFLAGS += \
-marm
@@ -71,11 +84,13 @@
if HAS_ANDROID_7_0_0
libhybris_common_la_CPPFLAGS += -DWANT_LINKER_N
endif
+if HAS_ANDROID_8_0_0
+libhybris_common_la_CPPFLAGS += -DWANT_LINKER_O
+endif
libhybris_common_la_LDFLAGS = \
-ldl \
-lrt \
-pthread \
-lc \
-lstdc++ \
- $(top_builddir)/properties/libandroid-properties.la \
-version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)"
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/hooks.c
^
|
@@ -65,16 +65,26 @@
#include <sys/syscall.h>
#include <sys/auxv.h>
#include <sys/prctl.h>
+#include <sys/uio.h>
#include <sys/mman.h>
#include <libgen.h>
#include <mntent.h>
#include <hybris/properties/properties.h>
+
+// using private implementations
+extern int my_property_set(const char *key, const char *value);
+extern int my_property_get(const char *key, char *value, const char *default_value);
+extern int my_property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);
+
#include <hybris/common/hooks.h>
#include <android-config.h>
+// this is also used in bionic:
+#define bool int
+
#ifdef WANT_ARM_TRACING
#include "wrappers.h"
#endif
@@ -84,17 +94,34 @@
static hybris_hook_cb hook_callback = NULL;
#ifdef WANT_ARM_TRACING
-static void (*_android_linker_init)(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), void *(_create_wrapper)(const char*, void*, int)) = NULL;
+static void (*_android_linker_init)(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support, void *(_create_wrapper)(const char*, void*, int)) = NULL;
#else
-static void (*_android_linker_init)(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*)) = NULL;
+static void (*_android_linker_init)(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support) = NULL;
#endif
-static void* (*_android_dlopen)(const char *filename, int flags) = NULL;
-static void* (*_android_dlsym)(void *handle, const char *symbol) = NULL;
-static void* (*_android_dlvsym)(void *handle, const char *symbol, const char* version) = NULL;
-static void* (*_android_dladdr)(void *addr, Dl_info *info) = NULL;
-static int (*_android_dlclose)(void *handle) = NULL;
-static const char* (*_android_dlerror)(void) = NULL;
+void *(*_android_dlopen)(const char* filename, int flag) = NULL;
+char *(*_android_dlerror)() = NULL;
+void *(*_android_dlsym)(void* handle, const char* symbol) = NULL;
+void *(*_android_dlvsym)(void* handle, const char* symbol, const char* version) = NULL;
+int (*_android_dladdr)(const void* addr, void* info) = NULL;
+int (*_android_dlclose)(void* handle) = NULL;
+void *(*_android_dl_unwind_find_exidx)(void *pc, int* pcount) = NULL;
+int (*_android_dl_iterate_phdr)(int (*cb)(void* info, size_t size, void* data), void* data) = NULL;
+void (*_android_get_LD_LIBRARY_PATH)(char* buffer, size_t buffer_size) = NULL;
+void (*_android_update_LD_LIBRARY_PATH)(const char* ld_library_path) = NULL;
+void *(*_android_dlopen_ext)(const char* filename, int flag, const void* extinfo) = NULL;
+void (*_android_set_application_target_sdk_version)(uint32_t target) = NULL;
+uint32_t (*_android_get_application_target_sdk_version)() = NULL;
+void *(*_android_create_namespace)(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ void* parent) = NULL;
+bool (*_android_init_anonymous_namespace)(const char* shared_libs_sonames,
+ const char* library_search_path) = NULL;
+void (*_android_dlwarning)(void* obj, void (*f)(void*, const char*)) = NULL;
+void *(*_android_get_exported_namespace)(const char* name) = NULL;
/* TODO:
* - Check if the int arguments at attr_set/get match the ones at Android
@@ -1276,6 +1303,36 @@
return pthread_rwlock_unlock(realrwlock);
}
+/* Bionic implementation of pthread_cleanup_push/pop doesn't support C++ exceptions
+ and thread cancelation. We only make sure to call the cleanup routine when
+ requested. We duplicate the bionic cleanup struct here for our purposes. */
+
+typedef void (*bionic___pthread_cleanup_func_t)(void*);
+
+typedef struct bionic___pthread_cleanup_t {
+ struct bionic___pthread_cleanup_t* __cleanup_prev; /* unused */
+ bionic___pthread_cleanup_func_t __cleanup_routine;
+ void* __cleanup_arg;
+} bionic___pthread_cleanup_t;
+
+static void _hybris_hook___pthread_cleanup_push(void *bionic_cleanup, void *routine, void *arg)
+{
+ bionic___pthread_cleanup_t *cleanup = bionic_cleanup;
+
+ TRACE_HOOK("cleanup %p routine %p arg %p", cleanup, routine, arg);
+ cleanup->__cleanup_routine = routine;
+ cleanup->__cleanup_arg = arg;
+}
+
+static void _hybris_hook___pthread_cleanup_pop(void *bionic_cleanup, int execute)
+{
+ bionic___pthread_cleanup_t *cleanup = bionic_cleanup;
+
+ TRACE_HOOK("cleanup %p execute %d", cleanup, execute);
+ if (execute)
+ cleanup->__cleanup_routine(cleanup->__cleanup_arg);
+}
+
#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
static pid_t _hybris_hook_pthread_gettid_np(pthread_t t)
@@ -1964,7 +2021,7 @@
{
TRACE_HOOK("pi %p name '%s' value '%s'", pi, name, value);
- return property_get(name, value, NULL);
+ return my_property_get(name, value, NULL);
}
static int _hybris_hook___system_property_foreach(void (*propfn)(const void *pi, void *cookie), void *cookie)
@@ -2035,7 +2092,7 @@
{
TRACE_HOOK("name '%s' value '%s'", name, value);
- return property_get(name, (char*) value, NULL);
+ return my_property_get(name, (char*) value, NULL);
}
int _hybris_hook_property_get(const char *key, char *value, const char *default_value)
@@ -2043,14 +2100,22 @@
TRACE_HOOK("key '%s' value '%s' default value '%s'",
key, value, default_value);
- return property_get(key, value, default_value);
+ return my_property_get(key, value, default_value);
+}
+
+int _hybris_hook_property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie)
+{
+ TRACE_HOOK("propfn '%p' cookie '%p'",
+ propfn, cookie);
+
+ return my_property_list(propfn, cookie);
}
int _hybris_hook_property_set(const char *key, const char *value)
{
TRACE_HOOK("key '%s' value '%s'", key, value);
- return property_set(key, value);
+ return my_property_set(key, value);
}
char *_hybris_hook_getenv(const char *name)
@@ -2403,6 +2468,66 @@
return getwc(_get_actual_fp(stream));
}
+static size_t _hybris_hook___fbufsize(FILE *stream)
+{
+ TRACE_HOOK("__fbufsize");
+ return __fbufsize(_get_actual_fp(stream));
+}
+
+static size_t _hybris_hook___fpending(FILE *stream)
+{
+ TRACE_HOOK("__fpending");
+ return __fpending(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___flbf(FILE *stream)
+{
+ TRACE_HOOK("__flbf");
+ return __flbf(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___freadable(FILE *stream)
+{
+ TRACE_HOOK("__freadable");
+ return __freadable(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___fwritable(FILE *stream)
+{
+ TRACE_HOOK("__fwritable");
+ return __fwritable(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___freading(FILE *stream)
+{
+ TRACE_HOOK("__freading");
+ return __freading(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___fwriting(FILE *stream)
+{
+ TRACE_HOOK("__fwriting");
+ return __fwriting(_get_actual_fp(stream));
+}
+
+static int _hybris_hook___fsetlocking(FILE *stream, int type)
+{
+ TRACE_HOOK("__fsetlocking");
+ return __fsetlocking(_get_actual_fp(stream), type);
+}
+
+static void _hybris_hook__flushlbf(void)
+{
+ TRACE_HOOK("_flushlbf");
+ _flushlbf();
+}
+
+static void _hybris_hook___fpurge(FILE *stream)
+{
+ TRACE_HOOK("__fpurge");
+ __fpurge(_get_actual_fp(stream));
+}
+
static void *_hybris_hook_dlopen(const char *filename, int flag)
{
TRACE("filename %s flag %i", filename, flag);
@@ -2445,21 +2570,128 @@
return android_dlerror();
}
+void *_hybris_hook_dl_unwind_find_exidx(void* pc, int* pcount)
+{
+ TRACE("pc %p, pcount %p", pc, pcount);
+
+ return _android_dl_unwind_find_exidx(pc, pcount);
+}
+
+int _hybris_hook_dl_iterate_phdr(int (*cb)(void* info, size_t size, void* data), void* data)
+{
+ TRACE("cb %p, data %p", cb, data);
+
+ return _android_dl_iterate_phdr(cb, data);
+}
+
+void _hybris_hook_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size)
+{
+ TRACE("buffer %p, buffer_size %zu\n", buffer_size);
+
+ _android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void _hybris_hook_android_update_LD_LIBRARY_PATH(const char* ld_library_path)
+{
+ TRACE("ld_library_path %s", ld_library_path);
+
+ _android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+void* _hybris_hook_android_dlopen_ext(const char* filename, int flag, const void* extinfo)
+{
+ TRACE("filename %s, flag %d, extinfo %s", filename, flag, extinfo);
+
+ return _android_dlopen_ext(filename, flag, extinfo);
+}
+
+void _hybris_hook_android_set_application_target_sdk_version(uint32_t target)
+{
+ TRACE("target %d", target);
+
+ android_set_application_target_sdk_version(target);
+}
+
+uint32_t _hybris_hook_android_get_application_target_sdk_version()
+{
+ TRACE("");
+
+ return _android_get_application_target_sdk_version();
+}
+
+void* _hybris_hook_android_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ void* parent)
+{
+ TRACE("name %s, ld_library_path %s, default_library_path %s, type %" PRIu64 ", permitted_when_isolated_path %s, parent %p", name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent);
+
+ return _android_create_namespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent);
+}
+
+bool _hybris_hook_android_init_anonymous_namespace(const char* shared_libs_sonames,
+ const char* library_search_path)
+{
+ TRACE("shared_libs_sonames %s, library_search_path %s", shared_libs_sonames, library_search_path);
+
+ return _android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
+}
+
+void _hybris_hook_android_dlwarning(void* obj, void (*f)(void*, const char*))
+{
+ TRACE("obj %p, f %p", obj, f);
+
+ _android_dlwarning(obj, f);
+}
+
+void* _hybris_hook_android_get_exported_namespace(const char* name)
+{
+ TRACE("name %s", name);
+
+ return _android_get_exported_namespace(name);
+}
+
+/* this was added while debugging in the hopes to get a backtrace from a double
+ * free crash. Unfortunately it fixes the problem so we cannot get a proper
+ * backtrace to fix the underlying problem. */
+void _hybris_hook_free(void *ptr)
+{
+ if (ptr) ((char*)ptr)[0] = 0;
+ free(ptr);
+}
+
#if !defined(cfree)
#define cfree free
#endif
+// old property hooks for pre-android 8 approach
+static struct _hook hooks_properties[] = {
+ HOOK_INDIRECT(property_get),
+ HOOK_INDIRECT(property_set),
+ HOOK_INDIRECT(property_list),
+ HOOK_INDIRECT(__system_property_get),
+ HOOK_INDIRECT(__system_property_read),
+ HOOK_TO(__system_property_set, _hybris_hook_property_set),
+ HOOK_INDIRECT(__system_property_foreach),
+ HOOK_INDIRECT(__system_property_find),
+ HOOK_INDIRECT(__system_property_serial),
+ HOOK_INDIRECT(__system_property_wait),
+ HOOK_INDIRECT(__system_property_update),
+ HOOK_INDIRECT(__system_property_add),
+ HOOK_INDIRECT(__system_property_wait_any),
+ HOOK_INDIRECT(__system_property_find_nth),
+};
+
static struct _hook hooks_common[] = {
- HOOK_DIRECT(property_get),
- HOOK_DIRECT(property_set),
- HOOK_INDIRECT(__system_property_get),
HOOK_DIRECT(getenv),
HOOK_DIRECT_NO_DEBUG(printf),
HOOK_INDIRECT(malloc),
- HOOK_DIRECT_NO_DEBUG(free),
+ HOOK_INDIRECT(free),
HOOK_DIRECT_NO_DEBUG(calloc),
- HOOK_DIRECT_NO_DEBUG(cfree),
+ HOOK_DIRECT_NO_DEBUG(free),
HOOK_DIRECT_NO_DEBUG(realloc),
HOOK_DIRECT_NO_DEBUG(memalign),
HOOK_DIRECT_NO_DEBUG(valloc),
@@ -2595,6 +2827,8 @@
HOOK_INDIRECT(pthread_rwlock_trywrlock),
HOOK_INDIRECT(pthread_rwlock_timedrdlock),
HOOK_INDIRECT(pthread_rwlock_timedwrlock),
+ HOOK_INDIRECT(__pthread_cleanup_push),
+ HOOK_INDIRECT(__pthread_cleanup_pop),
/* bionic-only pthread */
HOOK_TO(__pthread_gettid, _hybris_hook_pthread_gettid_np),
HOOK_INDIRECT(pthread_gettid_np),
@@ -2656,6 +2890,7 @@
HOOK_INDIRECT(setlinebuf),
HOOK_TO(__errno, __errno_location),
HOOK_INDIRECT(__set_errno),
+ HOOK_TO(__set_errno_internal, _hybris_hook___set_errno),
HOOK_TO(__progname, &program_invocation_name),
/* net specifics, to avoid __res_get_state */
HOOK_INDIRECT(getaddrinfo),
@@ -2672,6 +2907,17 @@
HOOK_INDIRECT(dlvsym),
HOOK_INDIRECT(dladdr),
HOOK_INDIRECT(dlclose),
+ HOOK_INDIRECT(dl_unwind_find_exidx),
+ HOOK_INDIRECT(dl_iterate_phdr),
+ HOOK_INDIRECT(android_get_LD_LIBRARY_PATH),
+ HOOK_INDIRECT(android_update_LD_LIBRARY_PATH),
+ HOOK_INDIRECT(android_dlopen_ext),
+ HOOK_INDIRECT(android_set_application_target_sdk_version),
+ HOOK_INDIRECT(android_get_application_target_sdk_version),
+ HOOK_INDIRECT(android_create_namespace),
+ HOOK_INDIRECT(android_init_anonymous_namespace),
+ HOOK_INDIRECT(android_dlwarning),
+ HOOK_INDIRECT(android_get_exported_namespace),
/* dirent.h */
HOOK_DIRECT_NO_DEBUG(opendir),
HOOK_DIRECT_NO_DEBUG(fdopendir),
@@ -2714,18 +2960,19 @@
HOOK_DIRECT_NO_DEBUG(getgrgid),
HOOK_DIRECT_NO_DEBUG(__cxa_atexit),
HOOK_DIRECT_NO_DEBUG(__cxa_finalize),
- HOOK_INDIRECT(__system_property_read),
- HOOK_TO(__system_property_set, _hybris_hook_property_set),
- HOOK_INDIRECT(__system_property_foreach),
- HOOK_INDIRECT(__system_property_find),
- HOOK_INDIRECT(__system_property_serial),
- HOOK_INDIRECT(__system_property_wait),
- HOOK_INDIRECT(__system_property_update),
- HOOK_INDIRECT(__system_property_add),
- HOOK_INDIRECT(__system_property_wait_any),
- HOOK_INDIRECT(__system_property_find_nth),
/* sys/prctl.h */
HOOK_INDIRECT(prctl),
+ /* stdio_ext.h */
+ HOOK_INDIRECT(__fbufsize),
+ HOOK_INDIRECT(__fpending),
+ HOOK_INDIRECT(__flbf),
+ HOOK_INDIRECT(__freadable),
+ HOOK_INDIRECT(__fwritable),
+ HOOK_INDIRECT(__freading),
+ HOOK_INDIRECT(__fwriting),
+ HOOK_INDIRECT(__fsetlocking),
+ HOOK_INDIRECT(_flushlbf),
+ HOOK_INDIRECT(__fpurge),
};
static struct _hook hooks_mm[] = {
@@ -2842,6 +3089,30 @@
hook_callback = callback;
}
+#define LINKER_NAME_JB "jb"
+#define LINKER_NAME_MM "mm"
+#define LINKER_NAME_N "n"
+#define LINKER_NAME_O "o"
+
+#if defined(WANT_LINKER_O)
+#define LINKER_VERSION_DEFAULT 27
+#define LINKER_NAME_DEFAULT LINKER_NAME_O
+#elif defined(WANT_LINKER_N)
+#define LINKER_VERSION_DEFAULT 25
+#define LINKER_NAME_DEFAULT LINKER_NAME_N
+#elif defined(WANT_LINKER_MM)
+#define LINKER_VERSION_DEFAULT 23
+#define LINKER_NAME_DEFAULT LINKER_NAME_MM
+#elif defined(WANT_LINKER_JB)
+#define LINKER_VERSION_DEFAULT 18
+#define LINKER_NAME_DEFAULT LINKER_NAME_JB
+#endif
+
+// create string version of default linker for get_android_sdk_version
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+#define LINKER_VERSION_DEFAULT_STRING STRINGIFY(LINKER_VERSION_DEFAULT)
+
static int get_android_sdk_version()
{
static int sdk_version = -1;
@@ -2849,19 +3120,27 @@
if (sdk_version > 0)
return sdk_version;
+ // in case android-init is patched we can use my_property_get. in case it
+ // is not use the default linker. this is such that we don't need the
+ // properties patch in android >=8, because properties are read via bionic
+ // libc.so starting from android 8, since it is much easier to use the
+ // bionic implementation and avoid having to implement all the fancy bionic
+ // property features which are mandatory now and cannot be stubbed as
+ // previously.
char value[PROP_VALUE_MAX];
- property_get("ro.build.version.sdk", value, "19");
+ my_property_get("ro.build.version.sdk", value, LINKER_VERSION_DEFAULT_STRING);
- sdk_version = 19;
- if (strlen(value) > 0)
+ sdk_version = LINKER_VERSION_DEFAULT;
+ if (strlen(value) > 0) {
sdk_version = atoi(value);
+ }
#ifdef UBUNTU_LINKER_OVERRIDES
/* We override both frieza and turbo here until they are ready to be
* upgraded to the newer linker. */
char device_name[PROP_VALUE_MAX];
memset(device_name, 0, sizeof(device_name));
- property_get("ro.build.product", device_name, "");
+ my_property_get("ro.build.product", device_name, "");
if (strlen(device_name) > 0) {
/* Force SDK version for both frieza/cooler and turbo for the time being */
if (strcmp(device_name, "frieza") == 0 ||
@@ -2890,6 +3169,7 @@
static intptr_t counter = -1;
void *found = NULL;
struct _hook key;
+ int sdk_version = -1;
/* First check if we have a callback registered which could
* give us a context specific hook implementation */
@@ -2902,6 +3182,7 @@
if (!sorted)
{
+ qsort(hooks_properties, HOOKS_SIZE(hooks_properties), sizeof(hooks_properties[0]), hook_cmp);
qsort(hooks_common, HOOKS_SIZE(hooks_common), sizeof(hooks_common[0]), hook_cmp);
qsort(hooks_mm, HOOKS_SIZE(hooks_mm), sizeof(hooks_mm[0]), hook_cmp);
sorted = 1;
@@ -2909,14 +3190,18 @@
/* Allow newer hooks to override those which are available for all versions */
key.name = sym;
-#if defined(WANT_LINKER_N)
- if (get_android_sdk_version() > 21)
- found = bsearch(&key, hooks_mm, HOOKS_SIZE(hooks_mm), sizeof(hooks_mm[0]), hook_cmp);
-#endif
-#if defined(WANT_LINKER_MM)
- if (get_android_sdk_version() > 21)
+ sdk_version = get_android_sdk_version();
+
+#if defined(WANT_LINKER_MM) || defined(WANT_LINKER_N) || defined(WANT_LINKER_O)
+ if (sdk_version > 21)
found = bsearch(&key, hooks_mm, HOOKS_SIZE(hooks_mm), sizeof(hooks_mm[0]), hook_cmp);
#endif
+ // make sure to skip the property hooks only when o.so is actually loaded
+ // since for testing and we sometimes set things like 99 as sdk version.
+ // The o linker is loaded when sdk_version >= 27 and exists.
+ if (!found && sdk_version < 27)
+ found = bsearch(&key, hooks_properties, HOOKS_SIZE(hooks_properties), sizeof(hooks_properties[0]), hook_cmp);
+
if (!found)
found = bsearch(&key, hooks_common, HOOKS_SIZE(hooks_common), sizeof(hooks_common[0]), hook_cmp);
@@ -2955,30 +3240,26 @@
{
void *handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (!handle) {
- fprintf(stderr, "ERROR: Failed to load hybris linker for Android SDK version %d\n",
- get_android_sdk_version());
+ fprintf(stderr, "ERROR: Failed to load hybris linker for Android SDK version %d: %s\n",
+ get_android_sdk_version(), dlerror());
return NULL;
}
return handle;
}
-#define LINKER_NAME_JB "jb"
-#define LINKER_NAME_MM "mm"
-#define LINKER_NAME_N "n"
-
-#if defined(WANT_LINKER_N)
-#define LINKER_NAME_DEFAULT LINKER_NAME_N
-#elif defined(WANT_LINKER_JB)
-#define LINKER_NAME_DEFAULT LINKER_NAME_JB
-#elif defined(WANT_LINKER_MM)
-#define LINKER_NAME_DEFAULT LINKER_NAME_MM
-#endif
-
static int linker_initialized = 0;
static void __hybris_linker_init()
{
LOGD("Linker initialization");
+
+ int enable_linker_gdb_support = 0;
+ const char *env = getenv("HYBRIS_ENABLE_LINKER_DEBUG_MAP");
+ if (env != NULL) {
+ if (strcmp(env, "1") == 0) {
+ enable_linker_gdb_support = 1;
+ }
+ }
int sdk_version = get_android_sdk_version();
@@ -2988,6 +3269,10 @@
/* See https://source.android.com/source/build-numbers.html for
* an overview over available SDK version numbers and which
* Android version they relate to. */
+#if defined(WANT_LINKER_O)
+ if (sdk_version <= 27)
+ name = LINKER_NAME_O;
+#endif
#if defined(WANT_LINKER_N)
if (sdk_version <= 25)
name = LINKER_NAME_N;
@@ -3002,7 +3287,11 @@
#endif
const char *linker_dir = LINKER_PLUGIN_DIR;
- const char *user_linker_dir = getenv("HYBRIS_LINKER_DIR");
+ /* getauxval to make sure users cannot load custom libraries into
+ * setuid processes */
+ const char *user_linker_dir = getauxval(AT_SECURE) ?
+ NULL :
+ getenv("HYBRIS_LINKER_DIR");
if (user_linker_dir)
linker_dir = user_linker_dir;
@@ -3017,19 +3306,34 @@
/* Load all necessary symbols we need from the linker */
_android_linker_init = dlsym(linker_handle, "android_linker_init");
_android_dlopen = dlsym(linker_handle, "android_dlopen");
+ _android_dlerror = dlsym(linker_handle, "android_dlerror");
_android_dlsym = dlsym(linker_handle, "android_dlsym");
_android_dlvsym = dlsym(linker_handle, "android_dlvsym");
_android_dladdr = dlsym(linker_handle, "android_dladdr");
_android_dlclose = dlsym(linker_handle, "android_dlclose");
- _android_dlerror = dlsym(linker_handle, "android_dlerror");
+ _android_dl_unwind_find_exidx = dlsym(linker_handle, "android_dl_unwind_find_exidx");
+ _android_dl_iterate_phdr = dlsym(linker_handle, "android_dl_iterate_phdr");
+ _android_get_LD_LIBRARY_PATH = dlsym(linker_handle, "android_get_LD_LIBRARY_PATH");
+ _android_update_LD_LIBRARY_PATH = dlsym(linker_handle, "android_update_LD_LIBRARY_PATH");
+ _android_dlopen_ext = dlsym(linker_handle, "android_dlopen_ext");
+ _android_set_application_target_sdk_version = dlsym(linker_handle, "android_set_application_target_sdk_version");
+ _android_get_application_target_sdk_version = dlsym(linker_handle, "android_get_application_target_sdk_version");
+ _android_create_namespace = dlsym(linker_handle, "android_create_namespace");
+ _android_init_anonymous_namespace = dlsym(linker_handle, "android_init_anonymous_namespace");
+ _android_dlwarning = dlsym(linker_handle, "android_dlwarning");
+ _android_get_exported_namespace = dlsym(linker_handle, "android_get_exported_namespace");
/* Now its time to setup the linker itself */
#ifdef WANT_ARM_TRACING
- _android_linker_init(sdk_version, __hybris_get_hooked_symbol, create_wrapper);
+ _android_linker_init(sdk_version, __hybris_get_hooked_symbol, enable_linker_gdb_support, create_wrapper);
#else
- _android_linker_init(sdk_version, __hybris_get_hooked_symbol);
+ _android_linker_init(sdk_version, __hybris_get_hooked_symbol, enable_linker_gdb_support);
#endif
+ if (_android_set_application_target_sdk_version) {
+ _android_set_application_target_sdk_version(sdk_version);
+ }
+
linker_initialized = 1;
}
@@ -3041,72 +3345,300 @@
* but several users are using android_* functions directly we
* have to export them here. */
-void *android_dlopen(const char *filename, int flag)
+void* android_dlopen(const char* filename, int flag)
{
ENSURE_LINKER_IS_LOADED();
- if (!_android_dlopen)
+ if (!_android_dlopen) {
return NULL;
+ }
- return _android_dlopen(filename,flag);
+ return _android_dlopen(filename, flag);
}
-void *android_dlsym(void *handle, const char *symbol)
+char* android_dlerror()
{
ENSURE_LINKER_IS_LOADED();
- if (!_android_dlsym)
+ if (!_android_dlerror) {
return NULL;
+ }
- return _android_dlsym(handle,symbol);
+ return _android_dlerror();
}
-void *android_dlvsym(void *handle, const char *symbol, const char* version)
+void* android_dlsym(void* handle, const char* symbol)
{
ENSURE_LINKER_IS_LOADED();
- if (!_android_dlvsym)
+ // do not use hybris properties for older linkers
+ if (get_android_sdk_version() < 27) {
+ if (!strcmp(symbol, "property_list")) {
+ return my_property_list;
+ }
+ if (!strcmp(symbol, "property_get")) {
+ return my_property_get;
+ }
+ if (!strcmp(symbol, "property_set")) {
+ return my_property_set;
+ }
+ }
+
+ if (!_android_dlsym) {
return NULL;
+ }
- return _android_dlvsym(handle,symbol, version);
+ return _android_dlsym(handle, symbol);
}
-int android_dlclose(void *handle)
+void* android_dlvsym(void* handle, const char* symbol, const char* version)
{
ENSURE_LINKER_IS_LOADED();
- if (!_android_dlclose)
- return -1;
+ if (!_android_dlvsym) {
+ return NULL;
+ }
+
+ return _android_dlvsym(handle, symbol, version);
+}
+
+int android_dladdr(const void* addr, void* info)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_dladdr) {
+ return 0;
+ }
+
+ return _android_dladdr(addr, info);
+}
+
+int android_dlclose(void* handle)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_dlclose) {
+ return 0;
+ }
return _android_dlclose(handle);
}
-const char *android_dlerror(void)
+void *android_dl_unwind_find_exidx(void *pc, int* pcount)
{
ENSURE_LINKER_IS_LOADED();
- if (!_android_dlerror)
+ if (!_android_dl_unwind_find_exidx) {
return NULL;
+ }
- return _android_dlerror();
+ return _android_dl_unwind_find_exidx(pc, pcount);
}
-void *hybris_dlopen(const char *filename, int flag)
+int android_dl_iterate_phdr(int (*cb)(void* info, size_t size, void* data), void* data)
{
- return android_dlopen(filename,flag);
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_dl_iterate_phdr) {
+ return 0;
+ }
+
+ return _android_dl_iterate_phdr(cb, data);
}
-void *hybris_dlsym(void *handle, const char *symbol)
+void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size)
{
- return android_dlsym(handle,symbol);
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_get_LD_LIBRARY_PATH) {
+ return;
+ }
+
+ _android_get_LD_LIBRARY_PATH(buffer, buffer_size);
}
-int hybris_dlclose(void *handle)
+void android_update_LD_LIBRARY_PATH(const char* ld_library_path)
{
- return android_dlclose(handle);
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_update_LD_LIBRARY_PATH) {
+ return;
+ }
+
+ _android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+void* android_dlopen_ext(const char* filename, int flag, const void* extinfo)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_dlopen_ext) {
+ return NULL;
+ }
+
+ return _android_dlopen_ext(filename, flag, extinfo);
}
-const char *hybris_dlerror(void)
+void android_set_application_target_sdk_version(uint32_t target)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_set_application_target_sdk_version) {
+ return;
+ }
+
+ _android_set_application_target_sdk_version(target);
+}
+
+uint32_t android_get_application_target_sdk_version()
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_get_application_target_sdk_version) {
+ return 0;
+ }
+
+ return _android_get_application_target_sdk_version();
+}
+
+struct android_namespace_t* android_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ struct android_namespace_t* parent)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_create_namespace) {
+ return NULL;
+ }
+
+ return _android_create_namespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent);
+}
+
+bool android_init_anonymous_namespace(const char* shared_libs_sonames,
+ const char* library_search_path)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_init_anonymous_namespace) {
+ return 0;
+ }
+
+ return _android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
+}
+
+void android_dlwarning(void* obj, void (*f)(void*, const char*))
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_dlwarning) {
+ return;
+ }
+
+ _android_dlwarning(obj, f);
+}
+
+struct android_namespace_t* android_get_exported_namespace(const char* name)
+{
+ ENSURE_LINKER_IS_LOADED();
+
+ if (!_android_get_exported_namespace) {
+ return NULL;
+ }
+
+ return _android_get_exported_namespace(name);
+}
+
+void* hybris_dlopen(const char* filename, int flag)
+{
+ return android_dlopen(filename, flag);
+}
+
+char* hybris_dlerror()
{
return android_dlerror();
}
+
+void* hybris_dlsym(void* handle, const char* symbol)
+{
+ return android_dlsym(handle, symbol);
+}
+
+void* hybris_dlvsym(void* handle, const char* symbol, const char* version)
+{
+ return android_dlvsym(handle, symbol, version);
+}
+
+int hybris_dladdr(const void* addr, void* info)
+{
+ return android_dladdr(addr, info);
+}
+
+int hybris_dlclose(void* handle)
+{
+ return android_dlclose(handle);
+}
+
+void *hybris_dl_unwind_find_exidx(void *pc, int* pcount)
+{
+ return android_dl_unwind_find_exidx(pc, pcount);
+}
+
+int hybris_dl_iterate_phdr(int (*cb)(void* info, size_t size, void* data), void* data)
+{
+ return android_dl_iterate_phdr(cb, data);
+}
+
+void hybris_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size)
+{
+ android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void hybris_update_LD_LIBRARY_PATH(const char* ld_library_path)
+{
+ android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+void* hybris_dlopen_ext(const char* filename, int flag, const void* extinfo)
+{
+ return android_dlopen_ext(filename, flag, extinfo);
+}
+
+void hybris_set_application_target_sdk_version(uint32_t target)
+{
+ android_set_application_target_sdk_version(target);
+}
+
+uint32_t hybris_get_application_target_sdk_version()
+{
+ return android_get_application_target_sdk_version();
+}
+
+void* hybris_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ void* parent)
+{
+ return android_create_namespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent);
+}
+
+bool hybris_init_anonymous_namespace(const char* shared_libs_sonames,
+ const char* library_search_path)
+{
+ return android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
+}
+
+void hybris_dlwarning(void* obj, void (*f)(void*, const char*))
+{
+ android_dlwarning(obj, f);
+}
+
+void* hybris_get_exported_namespace(const char* name)
+{
+ return android_get_exported_namespace(name);
+}
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/jb/linker.c
^
|
@@ -166,14 +166,18 @@
*/
extern void __attribute__((noinline)) rtld_db_dlactivity(void);
-static struct r_debug _r_debug = {1, NULL, &rtld_db_dlactivity,
+struct r_debug _r_debug = {1, NULL, &rtld_db_dlactivity,
RT_CONSISTENT, 0};
static struct link_map *r_debug_tail = 0;
static pthread_mutex_t _r_debug_lock = PTHREAD_MUTEX_INITIALIZER;
+static int _linker_enable_gdb_support = 0;
+
static void insert_soinfo_into_debug_map(soinfo * info)
{
+ if (!_linker_enable_gdb_support) return;
+
struct link_map * map;
/* Copy the necessary fields into the debug structure.
@@ -188,20 +192,52 @@
* about leaf libraries, and ordering it this way
* reduces the back-and-forth over the wire.
*/
+
+ ///// PATCHED: we don't want libhybris modifying glibc's
+ ///// link_map objects, which should not be linked
+ ///// to bionic's stripped link_map objects.
+ ///// ==> make a copy of the whole chain
+ if(r_debug_tail == 0 && _r_debug.r_map != 0) {
+ struct link_map *glibc_link_map = malloc(sizeof(struct link_map));
+ glibc_link_map->l_addr = _r_debug.r_map->l_addr;
+ glibc_link_map->l_name = _r_debug.r_map->l_name;
+ glibc_link_map->l_ld = _r_debug.r_map->l_ld;
+ glibc_link_map->l_next = _r_debug.r_map->l_next;
+ glibc_link_map->l_prev = _r_debug.r_map->l_prev;
+
+ r_debug_tail = glibc_link_map;
+
+ while(glibc_link_map->l_next != 0) {
+ struct link_map *copy_next_link_map = malloc(sizeof(struct link_map));
+ copy_next_link_map->l_addr = glibc_link_map->l_next->l_addr;
+ copy_next_link_map->l_name = glibc_link_map->l_next->l_name;
+ copy_next_link_map->l_ld = glibc_link_map->l_next->l_ld;
+ copy_next_link_map->l_next = glibc_link_map->l_next->l_next;
+ copy_next_link_map->l_prev = glibc_link_map->l_next->l_prev;
+
+ glibc_link_map->l_next = copy_next_link_map;
+ copy_next_link_map->l_prev = glibc_link_map;
+
+ glibc_link_map = copy_next_link_map;
+ }
+ }
+
if (r_debug_tail) {
- r_debug_tail->l_next = map;
- map->l_prev = r_debug_tail;
- map->l_next = 0;
+ r_debug_tail->l_prev = map;
+ map->l_next = r_debug_tail;
+ map->l_prev = 0;
} else {
_r_debug.r_map = map;
map->l_prev = 0;
map->l_next = 0;
}
- r_debug_tail = map;
+ _r_debug.r_map = r_debug_tail = map;
}
static void remove_soinfo_from_debug_map(soinfo * info)
{
+ if (!_linker_enable_gdb_support) return;
+
struct link_map * map = &(info->linkmap);
if (r_debug_tail == map)
@@ -2345,10 +2381,11 @@
}
#ifdef WANT_ARM_TRACING
-void android_linker_init(int sdk_version, void *(get_hooked_symbol)(const char*, const char*), void *(create_wrapper)(const char*, void*, int)) {
+void android_linker_init(int sdk_version, void *(get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support, void *(create_wrapper)(const char*, void*, int)) {
#else
-void android_linker_init(int sdk_version, void *(get_hooked_symbol)(const char*, const char*)) {
+void android_linker_init(int sdk_version, void *(get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support) {
#endif
(void) sdk_version;
_get_hooked_symbol = get_hooked_symbol;
+ _linker_enable_gdb_support = enable_linker_gdb_support;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/legacy_properties/cache.c
^
|
(renamed from libhybris/hybris/properties/cache.c)
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/legacy_properties/properties.c
^
|
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
+ * 2008 The Android Open Source Project
+ * 2013 Simon Busch <morphis@gravedo.de>
+ * 2013 Canonical Ltd
+ *
+ * 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.
+ *
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#define __USE_GNU
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <poll.h>
+
+#include <hybris/properties/properties.h>
+#include "properties_p.h"
+
+static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
+static int send_prop_msg_no_reply = 0;
+
+typedef struct prop_msg_s {
+ unsigned cmd;
+ char name[PROP_NAME_MAX];
+ char value[PROP_VALUE_MAX];
+} prop_msg_t;
+
+/* Get/Set a property from the Android Init property socket */
+static int send_prop_msg(prop_msg_t *msg,
+ void (*propfn)(const char *, const char *, void *),
+ void *cookie)
+{
+ union {
+ struct sockaddr_un addr;
+ struct sockaddr addr_g;
+ } addr;
+ socklen_t alen;
+ size_t namelen;
+ int s;
+ int r;
+ int result = -1;
+ int patched_init = 0;
+
+ /* if we tried to talk to the server in the past and didn't get a reply,
+ * it's fairly safe to say that init is not patched and this is all
+ * hopeless, so we should just quit while we're ahead
+ */
+ if (send_prop_msg_no_reply == 1)
+ return -EIO;
+
+ s = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (s < 0) {
+ return result;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ namelen = strlen(property_service_socket);
+ strncpy(addr.addr.sun_path, property_service_socket,
+ sizeof(addr.addr.sun_path));
+ addr.addr.sun_family = AF_LOCAL;
+ alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
+
+ if (TEMP_FAILURE_RETRY(connect(s, &addr.addr_g, alen) < 0)) {
+ close(s);
+ return result;
+ }
+
+ r = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg_t), 0));
+
+ if (r == sizeof(prop_msg_t)) {
+ // We successfully wrote to the property server, so use recv
+ // in case we need to get a property. Once the other side is
+ // finished, the socket is closed.
+ while ((r = recv(s, msg, sizeof(prop_msg_t), 0)) > 0) {
+ if (r != sizeof(prop_msg_t)) {
+ close(s);
+ return result;
+ }
+
+ /* If we got a reply, this is a patched init */
+ if (!patched_init)
+ patched_init = 1;
+
+ if (propfn)
+ propfn(msg->name, msg->value, cookie);
+ }
+
+ /* We also just get a close in case of setprop */
+ if ((r >= 0) && (patched_init ||
+ (msg->cmd == PROP_MSG_SETPROP))) {
+ result = 0;
+ } else {
+ send_prop_msg_no_reply = 1;
+ }
+ }
+
+ close(s);
+ return result;
+}
+
+int my_property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie)
+{
+ int err;
+ prop_msg_t msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = PROP_MSG_LISTPROP;
+
+ err = send_prop_msg(&msg, propfn, cookie);
+ if (err < 0)
+ /* fallback to property cache */
+ hybris_propcache_list((hybris_propcache_list_cb) propfn, cookie);
+
+ return 0;
+}
+
+static int property_get_socket(const char *key, char *value, const char *default_value)
+{
+ int err;
+ prop_msg_t msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = PROP_MSG_GETPROP;
+
+ if (key) {
+ strncpy(msg.name, key, sizeof(msg.name));
+ err = send_prop_msg(&msg, NULL, NULL);
+ if (err < 0)
+ return err;
+ }
+
+ /* In case it's null, just use the default */
+ if ((strlen(msg.value) == 0) && (default_value)) {
+ if (strlen(default_value) > PROP_VALUE_MAX -1) return -1;
+ strcpy(msg.value, default_value);
+ }
+
+ strcpy(value, msg.value);
+
+ return 0;
+}
+
+int my_property_get(const char *key, char *value, const char *default_value)
+{
+ char *ret = NULL;
+
+ if ((key) && (strlen(key) > PROP_NAME_MAX -1)) return -1;
+ if (value == NULL) return -1;
+
+
+ // Runtime cache will serialize property lookups within the process.
+ // This will increase latency if multiple threads are doing many
+ // parallel lookups to new properties, but the overhead should
+ // be offset with the caching eventually.
+ runtime_cache_lock();
+ if (runtime_cache_get(key, value) == 0) {
+ ret = value;
+ } else if (property_get_socket(key, value, default_value) == 0) {
+ runtime_cache_insert(key, value);
+ ret = value;
+ }
+ runtime_cache_unlock();
+
+ if (ret)
+ return strlen(ret);
+
+
+ /* In case the socket is not available, search the property file cache by hand */
+ ret = hybris_propcache_find(key);
+
+ if (ret) {
+ strcpy(value, ret);
+ return strlen(value);
+ } else if (default_value != NULL) {
+ strcpy(value, default_value);
+ return strlen(value);
+ } else {
+ value = '\0';
+ }
+
+ return 0;
+}
+
+int my_property_set(const char *key, const char *value)
+{
+ int err;
+ prop_msg_t msg;
+
+ if (key == 0) return -1;
+ if (value == 0) value = "";
+ if (strlen(key) > PROP_NAME_MAX -1) return -1;
+ if (strlen(value) > PROP_VALUE_MAX -1) return -1;
+
+ runtime_cache_lock();
+ runtime_cache_remove(key);
+ runtime_cache_unlock();
+
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = PROP_MSG_SETPROP;
+ strncpy(msg.name, key, sizeof(msg.name));
+ strncpy(msg.value, value, sizeof(msg.value));
+
+ err = send_prop_msg(&msg, NULL, NULL);
+ if (err < 0) {
+ return err;
+ }
+
+ return 0;
+}
+
+// vim:ts=4:sw=4:noexpandtab
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/legacy_properties/properties_p.h
^
|
(renamed from libhybris/hybris/properties/properties_p.h)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/legacy_properties/runtime_cache.c
^
|
(renamed from libhybris/hybris/properties/runtime_cache.c)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/mm/dlfcn.cpp
^
|
@@ -198,13 +198,13 @@
return do_dl_iterate_phdr(cb, data);
}
-void android_set_application_target_sdk_version(uint32_t target) {
+extern "C" void android_set_application_target_sdk_version(uint32_t target) {
// lock to avoid modification in the middle of dlopen.
ScopedPthreadMutexLocker locker(&g_dl_mutex);
set_application_target_sdk_version(target);
}
-uint32_t android_get_application_target_sdk_version() {
+extern "C" uint32_t android_get_application_target_sdk_version() {
return get_application_target_sdk_version();
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/mm/linker.cpp
^
|
@@ -141,18 +141,22 @@
void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity();
static pthread_mutex_t g__r_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-static r_debug _r_debug =
+r_debug _r_debug =
{1, nullptr, reinterpret_cast<uintptr_t>(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0};
-static link_map* r_debug_tail = 0;
+static link_map* r_debug_head = 0;
static void* (*_get_hooked_symbol)(const char *sym, const char *requester);
+static int _linker_enable_gdb_support = 0;
+
#ifdef WANT_ARM_TRACING
void *(*_create_wrapper)(const char *symbol, void *function, int wrapper_type);
#endif
static void insert_soinfo_into_debug_map(soinfo* info) {
+ if (!_linker_enable_gdb_support) return;
+
// Copy the necessary fields into the debug structure.
link_map* map = &(info->link_map_head);
map->l_addr = info->load_bias;
@@ -164,23 +168,43 @@
// gdb tends to care more about libc than it does
// about leaf libraries, and ordering it this way
// reduces the back-and-forth over the wire.
- if (r_debug_tail) {
- r_debug_tail->l_next = map;
- map->l_prev = r_debug_tail;
- map->l_next = 0;
+
+ ///// PATCHED: we don't want libhybris modifying glibc's
+ ///// link_map objects, which should not be linked
+ ///// to bionic's stripped link_map objects.
+ ///// ==> make a copy of the whole chain
+ if(r_debug_head == 0 && _r_debug.r_map != 0) {
+ link_map *glibc_link_map = new link_map(*_r_debug.r_map);
+ r_debug_head = glibc_link_map;
+
+ while(glibc_link_map->l_next != 0) {
+ link_map *copy_next_link_map = new link_map(*glibc_link_map->l_next);
+ glibc_link_map->l_next = copy_next_link_map;
+ copy_next_link_map->l_prev = glibc_link_map;
+
+ glibc_link_map = copy_next_link_map;
+ }
+ }
+
+ if (r_debug_head != 0) {
+ r_debug_head->l_prev = map;
+ map->l_next = r_debug_head;
+ map->l_prev = 0;
} else {
_r_debug.r_map = map;
map->l_prev = 0;
map->l_next = 0;
}
- r_debug_tail = map;
+ _r_debug.r_map = r_debug_head = map;
}
static void remove_soinfo_from_debug_map(soinfo* info) {
+ if (!_linker_enable_gdb_support) return;
+
link_map* map = &(info->link_map_head);
- if (r_debug_tail == map) {
- r_debug_tail = map->l_prev;
+ if (r_debug_head == map) {
+ r_debug_head = map->l_prev;
}
if (map->l_prev) {
@@ -3175,7 +3199,7 @@
map->l_next = nullptr;
_r_debug.r_map = map;
- r_debug_tail = map;
+ r_debug_head = map;
init_linker_info_for_gdb(linker_base);
@@ -3207,10 +3231,10 @@
}
// Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
- if (DEFAULT_HYBRIS_LD_LIBRARY_PATH)
- parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
- else
+ if (ldpath_env)
parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
parse_LD_PRELOAD(ldpreload_env);
somain = si;
@@ -3343,9 +3367,9 @@
}
#ifdef WANT_ARM_TRACING
-extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), void *(create_wrapper)(const char*, void*, int)) {
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support, void *(create_wrapper)(const char*, void*, int)) {
#else
-extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*)) {
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support) {
#endif
// Get a few environment variables.
const char* LD_DEBUG = getenv("HYBRIS_LD_DEBUG");
@@ -3360,16 +3384,17 @@
ldpreload_env = getenv("HYBRIS_LD_PRELOAD");
}
- if (DEFAULT_HYBRIS_LD_LIBRARY_PATH)
- parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
- else
+ if (ldpath_env)
parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
parse_LD_PRELOAD(ldpreload_env);
if (sdk_version > 0)
set_application_target_sdk_version(sdk_version);
_get_hooked_symbol = get_hooked_symbol;
+ _linker_enable_gdb_support = enable_linker_gdb_support;
#ifdef WANT_ARM_TRACING
_create_wrapper = create_wrapper;
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/n/Makefile.am
^
|
@@ -54,3 +54,9 @@
n_la_CPPFLAGS += \
-DTRACE_DEBUG=1
endif
+
+if WANT_ARM_TRACING
+n_la_CPPFLAGS += \
+ -DWANT_ARM_TRACING
+endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/n/dlfcn.cpp
^
|
@@ -142,22 +142,22 @@
return do_dl_iterate_phdr(cb, data);
}
-void android_set_application_target_sdk_version(uint32_t target) {
+extern "C" void android_set_application_target_sdk_version(uint32_t target) {
// lock to avoid modification in the middle of dlopen.
ScopedPthreadMutexLocker locker(&g_dl_mutex);
set_application_target_sdk_version(target);
}
-uint32_t android_get_application_target_sdk_version() {
+extern "C" uint32_t android_get_application_target_sdk_version() {
return get_application_target_sdk_version();
}
-void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
+extern "C" void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
get_dlwarning(obj, f);
}
-bool android_init_namespaces(const char* public_ns_sonames,
+extern "C" bool android_init_namespaces(const char* public_ns_sonames,
const char* anon_ns_library_path) {
ScopedPthreadMutexLocker locker(&g_dl_mutex);
bool success = init_namespaces(public_ns_sonames, anon_ns_library_path);
@@ -168,7 +168,7 @@
return success;
}
-android_namespace_t* android_create_namespace(const char* name,
+extern "C" android_namespace_t* android_create_namespace(const char* name,
const char* ld_library_path,
const char* default_library_path,
uint64_t type,
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/n/linker.cpp
^
|
@@ -68,6 +68,10 @@
#include "linker_non_pie.h"
#endif
+#ifdef WANT_ARM_TRACING
+#include "../wrappers.h"
+#endif
+
// Stay compatible with newer glibc
#ifndef R_AARCH64_TLS_TPREL64
#define R_AARCH64_TLS_TPREL64 R_AARCH64_TLS_TPREL
@@ -177,33 +181,51 @@
#if defined(__LP64__)
static const char* const kSystemLibDir = "/system/lib64";
static const char* const kVendorLibDir = "/vendor/lib64";
+static const char* const kVendorLibEglDir = "/vendor/lib64/egl";
static const char* const kOdmLibDir = "/odm/lib64";
+static const char* const kOdmLibEglDir = "/odm/lib64/egl";
static const char* const kAsanSystemLibDir = "/data/lib64";
static const char* const kAsanVendorLibDir = "/data/vendor/lib64";
+static const char* const kAsanVendorLibEglDir = "/data/vendor/lib64/egl";
static const char* const kAsanOdmLibDir = "/data/odm/lib64";
+static const char* const kAsanOdmLibEglDir = "/data/odm/lib64/egl";
#else
static const char* const kSystemLibDir = "/system/lib";
static const char* const kVendorLibDir = "/vendor/lib";
+static const char* const kVendorLibEglDir = "/vendor/lib/egl";
static const char* const kOdmLibDir = "/odm/lib";
+static const char* const kOdmLibEglDir = "/odm/lib/egl";
static const char* const kAsanSystemLibDir = "/data/lib";
static const char* const kAsanVendorLibDir = "/data/vendor/lib";
+static const char* const kAsanVendorLibEglDir = "/data/vendor/lib/egl";
static const char* const kAsanOdmLibDir = "/data/odm/lib";
+static const char* const kAsanOdmLibEglDir = "/data/odm/lib/egl";
#endif
static const char* const kDefaultLdPaths[] = {
kSystemLibDir,
- kVendorLibDir,
kOdmLibDir,
+ kVendorLibDir,
+
+ // libhybris support:
+ kVendorLibEglDir,
+ kOdmLibEglDir,
nullptr
};
static const char* const kAsanDefaultLdPaths[] = {
kAsanSystemLibDir,
kSystemLibDir,
- kAsanVendorLibDir,
- kVendorLibDir,
kAsanOdmLibDir,
kOdmLibDir,
+ kAsanVendorLibDir,
+ kVendorLibDir,
+
+ // libhybris support:
+ kAsanOdmLibEglDir,
+ kOdmLibEglDir,
+ kAsanVendorLibEglDir,
+ kVendorLibEglDir,
nullptr
};
@@ -348,6 +370,10 @@
static void* (*_get_hooked_symbol)(const char *sym, const char *requester);
+#ifdef WANT_ARM_TRACING
+void *(*_create_wrapper)(const char *symbol, void *function, int wrapper_type);
+#endif
+
static char __linker_dl_err_buf[768];
char* linker_get_error_buffer() {
@@ -2621,7 +2647,19 @@
uint32_t bind = ELF_ST_BIND(sym->st_info);
if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
+#ifdef WANT_ARM_TRACING
+ switch(ELF_ST_TYPE(sym->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ *symbol = reinterpret_cast<void*>(_create_wrapper((char*)symbol, (void*)found->resolve_symbol_address(sym), WRAPPER_DYNHOOK));
+ default:
+ *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+ }
+#else
*symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+#endif
return true;
}
@@ -2914,6 +2952,28 @@
return false;
}
}
+#ifdef WANT_ARM_TRACING
+ else
+ {
+ // this will be slower.
+ if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
+ return false;
+ }
+
+ if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
+ return false;
+ }
+
+ switch(ELF_ST_TYPE(s->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ sym_addr = (ElfW(Addr))_create_wrapper(sym_name, (void*)sym_addr, WRAPPER_HOOKED);
+ break;
+ }
+ }
+#endif
if (sym_addr == 0 && s == nullptr) {
// We only allow an undefined symbol if this is a weak reference...
@@ -2987,7 +3047,24 @@
}
}
#endif
- sym_addr = lsi->resolve_symbol_address(s);
+
+#ifdef WANT_ARM_TRACING
+ switch(ELF_ST_TYPE(s->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ sym_addr = (ElfW(Addr))_create_wrapper(sym_name,
+ (void*)lsi->resolve_symbol_address(s), WRAPPER_UNHOOKED);
+ break;
+ default:
+ sym_addr = lsi->resolve_symbol_address(s);
+ break;
+ }
+#else
+ sym_addr = lsi->resolve_symbol_address(s);
+#endif
+
#if !defined(__LP64__)
if (protect_segments) {
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
@@ -4484,10 +4561,10 @@
#endif
// Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
- if (DEFAULT_HYBRIS_LD_LIBRARY_PATH)
- parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
- else
+ if (ldpath_env)
parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
parse_LD_PRELOAD(ldpreload_env);
parse_LD_SHIM_LIBS(ldshim_libs_env);
@@ -4624,7 +4701,11 @@
__libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
}
-extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*)) {
+#ifdef WANT_ARM_TRACING
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support, void *(create_wrapper)(const char*, void*, int)) {
+#else
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support) {
+#endif
// Get a few environment variables.
const char* LD_DEBUG = getenv("HYBRIS_LD_DEBUG");
if (LD_DEBUG != nullptr) {
@@ -4638,16 +4719,20 @@
ldpreload_env = getenv("HYBRIS_LD_PRELOAD");
}
- if (DEFAULT_HYBRIS_LD_LIBRARY_PATH)
- parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
- else
+ if (ldpath_env)
parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
parse_LD_PRELOAD(ldpreload_env);
if (sdk_version > 0)
set_application_target_sdk_version(sdk_version);
_get_hooked_symbol = get_hooked_symbol;
+ _linker_enable_gdb_support = enable_linker_gdb_support;
+#ifdef WANT_ARM_TRACING
+ _create_wrapper = create_wrapper;
+#endif
}
#ifdef DISABLED_FOR_HYBRIS_SUPPORT
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/n/linker_gdb_support.cpp
^
|
@@ -31,28 +31,52 @@
{1, nullptr, reinterpret_cast<uintptr_t>(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0};
static pthread_mutex_t g__r_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-static link_map* r_debug_tail = nullptr;
+static link_map* r_debug_head = nullptr;
+
+int _linker_enable_gdb_support = 0;
void insert_link_map_into_debug_map(link_map* map) {
+ if (!_linker_enable_gdb_support) return;
+
// Stick the new library at the end of the list.
// gdb tends to care more about libc than it does
// about leaf libraries, and ordering it this way
// reduces the back-and-forth over the wire.
- if (r_debug_tail != nullptr) {
- r_debug_tail->l_next = map;
- map->l_prev = r_debug_tail;
- map->l_next = nullptr;
+
+ ///// PATCHED: we don't want libhybris modifying glibc's
+ ///// link_map objects, which should not be linked
+ ///// to bionic's stripped link_map objects.
+ ///// ==> make a copy of the whole chain
+ if(r_debug_head == nullptr && _r_debug.r_map != nullptr) {
+ link_map *glibc_link_map = new link_map(*_r_debug.r_map);
+ r_debug_head = glibc_link_map;
+
+ while(glibc_link_map->l_next != nullptr) {
+ link_map *copy_next_link_map = new link_map(*glibc_link_map->l_next);
+ glibc_link_map->l_next = copy_next_link_map;
+ copy_next_link_map->l_prev = glibc_link_map;
+
+ glibc_link_map = copy_next_link_map;
+ }
+ }
+
+ if (r_debug_head != nullptr) {
+ r_debug_head->l_prev = map;
+ map->l_next = r_debug_head;
+ map->l_prev = nullptr;
} else {
_r_debug.r_map = map;
map->l_prev = nullptr;
map->l_next = nullptr;
}
- r_debug_tail = map;
+ _r_debug.r_map = r_debug_head = map;
}
void remove_link_map_from_debug_map(link_map* map) {
- if (r_debug_tail == map) {
- r_debug_tail = map->l_prev;
+ if (!_linker_enable_gdb_support) return;
+
+ if (r_debug_head == map) {
+ r_debug_head = map->l_next;
}
if (map->l_prev) {
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/n/linker_gdb_support.h
^
|
@@ -28,6 +28,7 @@
void notify_gdb_of_libraries();
extern struct r_debug _r_debug;
+extern int _linker_enable_gdb_support;
__END_DECLS
|
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/MODULE_LICENSE_BSD
^
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/Makefile.am
^
|
@@ -0,0 +1,74 @@
+bionic = $(top_srcdir)/common/o/bionic
+bionic_libc = $(bionic)/libc
+
+modlibexecdir = $(libdir)/libhybris/linker
+modlibexec_LTLIBRARIES = o.la
+
+ARCH_FLAGS =
+
+AM_CFLAGS = \
+ -std=gnu99
+
+AM_CPPFLAGS = \
+ -fno-stack-protector \
+ -Wstrict-overflow=5
+
+AM_CXXFLAGS = \
+ -std=gnu++11 \
+ -Wold-style-cast
+
+o_la_SOURCES = \
+ hybris_compat.cpp \
+ dlfcn.cpp \
+ linker_allocator.cpp \
+ linker_block_allocator.cpp \
+ linker.cpp \
+ linker_cfi.cpp \
+ linker_config.cpp \
+ linker_dlwarning.cpp \
+ linker_gdb_support.cpp \
+ linker_globals.cpp \
+ linker_logger.cpp \
+ linker_main.cpp \
+ linker_mapped_file_fragment.cpp \
+ linker_memory.cpp \
+ linker_namespaces.cpp \
+ linker_phdr.cpp \
+ linker_sdk_versions.cpp \
+ linker_soinfo.cpp \
+ linker_utils.cpp \
+ rt.cpp \
+ ../strlcpy.c \
+ ../strlcat.c
+o_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/common \
+ -I$(bionic_libc)/ \
+ -I$(bionic_libc)/include \
+ -DDEFAULT_HYBRIS_LD_LIBRARY_PATH="\"@DEFAULT_HYBRIS_LD_LIBRARY_PATH@\"" \
+ $(ARCH_FLAGS) \
+ $(ANDROID_HEADERS_CFLAGS)
+
+if HAS_ANDROID_9_0_0
+o_la_CPPFLAGS += -DHAS_ANDROID_9_0_0
+endif
+
+o_la_LDFLAGS = \
+ -lsupc++ \
+ -module \
+ -avoid-version
+
+if WANT_DEBUG
+o_la_CPPFLAGS += \
+ -DTRACE_DEBUG=1
+else
+o_la_CPPFLAGS += \
+ -DTRACE_DEBUG=1
+endif
+
+if WANT_ARM_TRACING
+o_la_CPPFLAGS += \
+ -DWANT_ARM_TRACING
+endif
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/async_safe/log.h
^
|
@@ -0,0 +1,26 @@
+#ifndef thatasyncsafeheaderthingy_replacement__
+#define thatasyncsafeheaderthingy_replacement__
+
+enum {
+ ANDROID_LOG_UNKNOWN = 0,
+ ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
+
+ ANDROID_LOG_VERBOSE,
+ ANDROID_LOG_DEBUG,
+ ANDROID_LOG_INFO,
+ ANDROID_LOG_WARN,
+ ANDROID_LOG_ERROR,
+ ANDROID_LOG_FATAL,
+
+ ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
+};
+
+#define async_safe_fatal(...) { fprintf(stderr, __VA_ARGS__); abort(); }
+
+#define async_safe_format_fd(...) dprintf(__VA_ARGS)
+
+// Don't really care about verbose/debug logs for now
+#define async_safe_format_log_va_list(loglevel, category, format, ...) { if (loglevel > ANDROID_LOG_INFO) { vfprintf(stderr, format, __VA_ARGS__); } }
+
+#endif
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/bionic/pthread_internal.h
^
|
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _PTHREAD_INTERNAL_H_
+#define _PTHREAD_INTERNAL_H_
+
+#include <pthread.h>
+#include <stdatomic.h>
+
+#include "private/bionic_lock.h"
+#include "private/bionic_tls.h"
+
+/* Has the thread been detached by a pthread_join or pthread_detach call? */
+#define PTHREAD_ATTR_FLAG_DETACHED 0x00000001
+
+/* Has the thread been joined by another thread? */
+#define PTHREAD_ATTR_FLAG_JOINED 0x00000002
+
+class pthread_key_data_t {
+ public:
+ uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
+ void* data;
+};
+
+enum ThreadJoinState {
+ THREAD_NOT_JOINED,
+ THREAD_EXITED_NOT_JOINED,
+ THREAD_JOINED,
+ THREAD_DETACHED
+};
+
+class thread_local_dtor;
+
+class pthread_internal_t {
+ public:
+ class pthread_internal_t* next;
+ class pthread_internal_t* prev;
+
+ pid_t tid;
+
+ private:
+ pid_t cached_pid_;
+
+ public:
+ pid_t invalidate_cached_pid() {
+ pid_t old_value;
+ get_cached_pid(&old_value);
+ set_cached_pid(0);
+ return old_value;
+ }
+
+ void set_cached_pid(pid_t value) {
+ cached_pid_ = value;
+ }
+
+ bool get_cached_pid(pid_t* cached_pid) {
+ *cached_pid = cached_pid_;
+ return (*cached_pid != 0);
+ }
+
+ pthread_attr_t attr;
+
+ _Atomic(ThreadJoinState) join_state;
+
+ //__pthread_cleanup_t* cleanup_stack;
+
+ void* (*start_routine)(void*);
+ void* start_routine_arg;
+ void* return_value;
+
+ void* alternate_signal_stack;
+
+ Lock startup_handshake_lock;
+
+ size_t mmap_size;
+
+ thread_local_dtor* thread_local_dtors;
+
+ void* tls[BIONIC_TLS_SLOTS];
+
+ pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
+
+ /*
+ * The dynamic linker implements dlerror(3), which makes it hard for us to implement this
+ * per-thread buffer by simply using malloc(3) and free(3).
+ */
+#define __BIONIC_DLERROR_BUFFER_SIZE 512
+ char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
+
+ struct bionic_tls* bionic_tls;
+};
+
+int __init_thread(pthread_internal_t* thread);
+bool __init_tls(pthread_internal_t* thread);
+void __init_thread_stack_guard(pthread_internal_t* thread);
+void __init_alternate_signal_stack(pthread_internal_t*);
+
+pthread_t __pthread_internal_add(pthread_internal_t* thread);
+pthread_internal_t* __pthread_internal_find(pthread_t pthread_id);
+void __pthread_internal_remove(pthread_internal_t* thread);
+void __pthread_internal_remove_and_free(pthread_internal_t* thread);
+
+// Make __get_thread() inlined for performance reason. See http://b/19825434.
+static inline pthread_internal_t* __get_thread() {
+ void** tls = __get_tls();
+ if (tls) {
+ return reinterpret_cast<pthread_internal_t*>(tls[TLS_SLOT_THREAD_ID]);
+ }
+
+ // This happens when called during libc initialization before TLS has been initialized.
+ return nullptr;
+}
+
+static inline bionic_tls& __get_bionic_tls() {
+ return *__get_thread()->bionic_tls;
+}
+
+void pthread_key_clean_all(void);
+
+// SIGSTKSZ (8kB) is not big enough.
+// snprintf to a stack buffer of size PATH_MAX consumes ~7kB of stack.
+// Also, on 64-bit, logging uses more than 8kB by itself:
+// https://code.google.com/p/android/issues/detail?id=187064
+#define SIGNAL_STACK_SIZE_WITHOUT_GUARD_PAGE (16 * 1024)
+
+/*
+ * Traditionally we gave threads a 1MiB stack. When we started
+ * allocating per-thread alternate signal stacks to ease debugging of
+ * stack overflows, we subtracted the same amount we were using there
+ * from the default thread stack size. This should keep memory usage
+ * roughly constant.
+ */
+#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGNAL_STACK_SIZE_WITHOUT_GUARD_PAGE)
+
+// Leave room for a guard page in the internally created signal stacks.
+#define SIGNAL_STACK_SIZE (SIGNAL_STACK_SIZE_WITHOUT_GUARD_PAGE + PAGE_SIZE)
+
+/* Needed by fork. */
+extern void __bionic_atfork_run_prepare();
+extern void __bionic_atfork_run_child();
+extern void __bionic_atfork_run_parent();
+
+#endif /* _PTHREAD_INTERNAL_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/endian.h
^
|
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_BASE_ENDIAN_H
+#define ANDROID_BASE_ENDIAN_H
+
+/* A cross-platform equivalent of bionic's <sys/endian.h>. */
+
+#if defined(__BIONIC__)
+
+#include <sys/endian.h>
+
+#elif defined(__GLIBC__)
+
+/* glibc's <endian.h> is like bionic's <sys/endian.h>. */
+#include <endian.h>
+
+/* glibc keeps htons and htonl in <netinet/in.h>. */
+#include <netinet/in.h>
+
+/* glibc doesn't have the 64-bit variants. */
+#define htonq(x) htobe64(x)
+#define ntohq(x) be64toh(x)
+
+/* glibc has different names to BSD for these. */
+#define betoh16(x) be16toh(x)
+#define betoh32(x) be32toh(x)
+#define betoh64(x) be64toh(x)
+
+#else
+
+/* Mac OS and Windows have nothing. */
+
+#define __LITTLE_ENDIAN 1234
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+
+#define __BIG_ENDIAN 4321
+#define BIG_ENDIAN __BIG_ENDIAN
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#define htons(x) __builtin_bswap16(x)
+#define htonl(x) __builtin_bswap32(x)
+#define htonq(x) __builtin_bswap64(x)
+
+#define ntohs(x) __builtin_bswap16(x)
+#define ntohl(x) __builtin_bswap32(x)
+#define ntohq(x) __builtin_bswap64(x)
+
+#define htobe16(x) __builtin_bswap16(x)
+#define htobe32(x) __builtin_bswap32(x)
+#define htobe64(x) __builtin_bswap64(x)
+
+#define betoh16(x) __builtin_bswap16(x)
+#define betoh32(x) __builtin_bswap32(x)
+#define betoh64(x) __builtin_bswap64(x)
+
+#define htole16(x) (x)
+#define htole32(x) (x)
+#define htole64(x) (x)
+
+#define letoh16(x) (x)
+#define letoh32(x) (x)
+#define letoh64(x) (x)
+
+#define be16toh(x) __builtin_bswap16(x)
+#define be32toh(x) __builtin_bswap32(x)
+#define be64toh(x) __builtin_bswap64(x)
+
+#define le16toh(x) (x)
+#define le32toh(x) (x)
+#define le64toh(x) (x)
+
+#endif
+
+#endif // ANDROID_BASE_ENDIAN_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/errors.h
^
|
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+// Portable error handling functions. This is only necessary for host-side
+// code that needs to be cross-platform; code that is only run on Unix should
+// just use errno and strerror() for simplicity.
+//
+// There is some complexity since Windows has (at least) three different error
+// numbers, not all of which share the same type:
+// * errno: for C runtime errors.
+// * GetLastError(): Windows non-socket errors.
+// * WSAGetLastError(): Windows socket errors.
+// errno can be passed to strerror() on all platforms, but the other two require
+// special handling to get the error string. Refer to Microsoft documentation
+// to determine which error code to check for each function.
+
+#ifndef ANDROID_BASE_ERRORS_H
+#define ANDROID_BASE_ERRORS_H
+
+#include <string>
+
+namespace android {
+namespace base {
+
+// Returns a string describing the given system error code. |error_code| must
+// be errno on Unix or GetLastError()/WSAGetLastError() on Windows. Passing
+// errno on Windows has undefined behavior.
+std::string SystemErrorCodeToString(int error_code);
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_ERRORS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/file.h
^
|
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_FILE_H
+#define ANDROID_BASE_FILE_H
+
+#include <sys/stat.h>
+#include <string>
+
+#if !defined(_WIN32) && !defined(O_BINARY)
+#define O_BINARY 0
+#endif
+
+namespace android {
+namespace base {
+
+bool ReadFdToString(int fd, std::string* content);
+bool ReadFileToString(const std::string& path, std::string* content,
+ bool follow_symlinks = false);
+
+bool WriteStringToFile(const std::string& content, const std::string& path,
+ bool follow_symlinks = false);
+bool WriteStringToFd(const std::string& content, int fd);
+
+#if !defined(_WIN32)
+bool WriteStringToFile(const std::string& content, const std::string& path,
+ mode_t mode, uid_t owner, gid_t group,
+ bool follow_symlinks = false);
+#endif
+
+bool ReadFully(int fd, void* data, size_t byte_count);
+bool WriteFully(int fd, const void* data, size_t byte_count);
+
+bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);
+
+#if !defined(_WIN32)
+bool Realpath(const std::string& path, std::string* result);
+bool Readlink(const std::string& path, std::string* result);
+#endif
+
+std::string GetExecutablePath();
+std::string GetExecutableDirectory();
+
+// Like the regular basename and dirname, but thread-safe on all
+// platforms and capable of correctly handling exotic Windows paths.
+std::string Basename(const std::string& path);
+std::string Dirname(const std::string& path);
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_FILE_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/logging.h
^
|
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_LOGGING_H
+#define ANDROID_BASE_LOGGING_H
+
+//
+// Google-style C++ logging.
+//
+
+// This header provides a C++ stream interface to logging.
+//
+// To log:
+//
+// LOG(INFO) << "Some text; " << some_value;
+//
+// Replace `INFO` with any severity from `enum LogSeverity`.
+//
+// To log the result of a failed function and include the string
+// representation of `errno` at the end:
+//
+// PLOG(ERROR) << "Write failed";
+//
+// The output will be something like `Write failed: I/O error`.
+// Remember this as 'P' as in perror(3).
+//
+// To output your own types, simply implement operator<< as normal.
+//
+// By default, output goes to logcat on Android and stderr on the host.
+// A process can use `SetLogger` to decide where all logging goes.
+// Implementations are provided for logcat, stderr, and dmesg.
+
+// This header also provides assertions:
+//
+// CHECK(must_be_true);
+// CHECK_EQ(a, b) << z_is_interesting_too;
+
+// NOTE: For Windows, you must include logging.h after windows.h to allow the
+// following code to suppress the evil ERROR macro:
+#ifdef _WIN32
+// windows.h includes wingdi.h which defines an evil macro ERROR.
+#ifdef ERROR
+#undef ERROR
+#endif
+#endif
+
+#include <functional>
+#include <memory>
+#include <ostream>
+
+#include "android-base/macros.h"
+
+namespace android {
+namespace base {
+
+enum LogSeverity {
+ VERBOSE,
+ DEBUG,
+ INFO,
+ WARNING,
+ ERROR,
+ FATAL_WITHOUT_ABORT,
+ FATAL,
+};
+
+enum LogId {
+ DEFAULT,
+ MAIN,
+ SYSTEM,
+};
+
+using LogFunction = std::function<void(LogId, LogSeverity, const char*, const char*,
+ unsigned int, const char*)>;
+using AbortFunction = std::function<void(const char*)>;
+
+void KernelLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
+void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
+
+void DefaultAborter(const char* abort_message);
+
+#ifdef __ANDROID__
+// We expose this even though it is the default because a user that wants to
+// override the default log buffer will have to construct this themselves.
+class LogdLogger {
+ public:
+ explicit LogdLogger(LogId default_log_id = android::base::MAIN);
+
+ void operator()(LogId, LogSeverity, const char* tag, const char* file,
+ unsigned int line, const char* message);
+
+ private:
+ LogId default_log_id_;
+};
+#endif
+
+// Configure logging based on ANDROID_LOG_TAGS environment variable.
+// We need to parse a string that looks like
+//
+// *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
+//
+// The tag (or '*' for the global level) comes first, followed by a colon and a
+// letter indicating the minimum priority level we're expected to log. This can
+// be used to reveal or conceal logs with specific tags.
+#ifdef __ANDROID__
+#define INIT_LOGGING_DEFAULT_LOGGER LogdLogger()
+#else
+#define INIT_LOGGING_DEFAULT_LOGGER StderrLogger
+#endif
+void InitLogging(char* argv[],
+ LogFunction&& logger = INIT_LOGGING_DEFAULT_LOGGER,
+ AbortFunction&& aborter = DefaultAborter);
+#undef INIT_LOGGING_DEFAULT_LOGGER
+
+// Replace the current logger.
+void SetLogger(LogFunction&& logger);
+
+// Replace the current aborter.
+void SetAborter(AbortFunction&& aborter);
+
+class ErrnoRestorer {
+ public:
+ ErrnoRestorer()
+ : saved_errno_(errno) {
+ }
+
+ ~ErrnoRestorer() {
+ errno = saved_errno_;
+ }
+
+ // Allow this object to be used as part of && operation.
+ operator bool() const {
+ return true;
+ }
+
+ private:
+ const int saved_errno_;
+
+ DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
+};
+
+// A helper macro that produces an expression that accepts both a qualified name and an
+// unqualified name for a LogSeverity, and returns a LogSeverity value.
+// Note: DO NOT USE DIRECTLY. This is an implementation detail.
+#define SEVERITY_LAMBDA(severity) ([&]() { \
+ using ::android::base::VERBOSE; \
+ using ::android::base::DEBUG; \
+ using ::android::base::INFO; \
+ using ::android::base::WARNING; \
+ using ::android::base::ERROR; \
+ using ::android::base::FATAL_WITHOUT_ABORT; \
+ using ::android::base::FATAL; \
+ return (severity); }())
+
+// Defines whether the given severity will be logged or silently swallowed.
+#define WOULD_LOG(severity) \
+ UNLIKELY((SEVERITY_LAMBDA(severity)) >= ::android::base::GetMinimumLogSeverity())
+
+// Get an ostream that can be used for logging at the given severity and to the default
+// destination.
+//
+// Notes:
+// 1) This will not check whether the severity is high enough. One should use WOULD_LOG to filter
+// usage manually.
+// 2) This does not save and restore errno.
+#define LOG_STREAM(severity) LOG_STREAM_TO(DEFAULT, severity)
+
+// Get an ostream that can be used for logging at the given severity and to the
+// given destination. The same notes as for LOG_STREAM apply.
+#define LOG_STREAM_TO(dest, severity) \
+ ::android::base::LogMessage(__FILE__, __LINE__, \
+ ::android::base::dest, \
+ SEVERITY_LAMBDA(severity), -1).stream()
+
+// Logs a message to logcat on Android otherwise to stderr. If the severity is
+// FATAL it also causes an abort. For example:
+//
+// LOG(FATAL) << "We didn't expect to reach here";
+#define LOG(severity) LOG_TO(DEFAULT, severity)
+
+// Logs a message to logcat with the specified log ID on Android otherwise to
+// stderr. If the severity is FATAL it also causes an abort.
+// Use an if-else statement instead of just an if statement here. So if there is a
+// else statement after LOG() macro, it won't bind to the if statement in the macro.
+// do-while(0) statement doesn't work here. Because we need to support << operator
+// following the macro, like "LOG(DEBUG) << xxx;".
+
+#define LOG_TO(dest, severity) \
+ WOULD_LOG(severity) && \
+ ::android::base::ErrnoRestorer() && \
+ LOG_STREAM_TO(dest, severity)
+
+// A variant of LOG that also logs the current errno value. To be used when
+// library calls fail.
+#define PLOG(severity) PLOG_TO(DEFAULT, severity)
+
+// Behaves like PLOG, but logs to the specified log ID.
+#define PLOG_TO(dest, severity) \
+ WOULD_LOG(SEVERITY_LAMBDA(severity)) && \
+ ::android::base::ErrnoRestorer() && \
+ ::android::base::LogMessage(__FILE__, __LINE__, \
+ ::android::base::dest, \
+ SEVERITY_LAMBDA(severity), errno).stream()
+
+// Marker that code is yet to be implemented.
+#define UNIMPLEMENTED(level) \
+ LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
+
+#ifdef __clang_analyzer__
+// ClangL static analyzer does not see the conditional statement inside
+// LogMessage's destructor that will abort on FATAL severity.
+#define ABORT_AFTER_LOG_FATAL for (;;abort())
+#else
+#define ABORT_AFTER_LOG_FATAL
+#endif
+
+// Check whether condition x holds and LOG(FATAL) if not. The value of the
+// expression x is only evaluated once. Extra logging can be appended using <<
+// after. For example:
+//
+// CHECK(false == true) results in a log message of
+// "Check failed: false == true".
+#define CHECK(x) \
+ LIKELY((x)) || \
+ ABORT_AFTER_LOG_FATAL \
+ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \
+ ::android::base::FATAL, -1).stream() \
+ << "Check failed: " #x << " "
+
+// Helper for CHECK_xx(x,y) macros.
+#define CHECK_OP(LHS, RHS, OP) \
+ for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \
+ UNLIKELY(!(_values.lhs OP _values.rhs)); \
+ /* empty */) \
+ ABORT_AFTER_LOG_FATAL \
+ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \
+ ::android::base::FATAL, -1).stream() \
+ << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
+ << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "
+
+// Check whether a condition holds between x and y, LOG(FATAL) if not. The value
+// of the expressions x and y is evaluated once. Extra logging can be appended
+// using << after. For example:
+//
+// CHECK_NE(0 == 1, false) results in
+// "Check failed: false != false (0==1=false, false=false) ".
+#define CHECK_EQ(x, y) CHECK_OP(x, y, == )
+#define CHECK_NE(x, y) CHECK_OP(x, y, != )
+#define CHECK_LE(x, y) CHECK_OP(x, y, <= )
+#define CHECK_LT(x, y) CHECK_OP(x, y, < )
+#define CHECK_GE(x, y) CHECK_OP(x, y, >= )
+#define CHECK_GT(x, y) CHECK_OP(x, y, > )
+
+// Helper for CHECK_STRxx(s1,s2) macros.
+#define CHECK_STROP(s1, s2, sense) \
+ while (UNLIKELY((strcmp(s1, s2) == 0) != (sense))) \
+ ABORT_AFTER_LOG_FATAL \
+ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \
+ ::android::base::FATAL, -1).stream() \
+ << "Check failed: " << "\"" << (s1) << "\"" \
+ << ((sense) ? " == " : " != ") << "\"" << (s2) << "\""
+
+// Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not.
+#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
+
+// Perform the pthread function call(args), LOG(FATAL) on error.
+#define CHECK_PTHREAD_CALL(call, args, what) \
+ do { \
+ int rc = call args; \
+ if (rc != 0) { \
+ errno = rc; \
+ ABORT_AFTER_LOG_FATAL \
+ PLOG(FATAL) << #call << " failed for " << (what); \
+ } \
+ } while (false)
+
+// CHECK that can be used in a constexpr function. For example:
+//
+// constexpr int half(int n) {
+// return
+// DCHECK_CONSTEXPR(n >= 0, , 0)
+// CHECK_CONSTEXPR((n & 1) == 0),
+// << "Extra debugging output: n = " << n, 0)
+// n / 2;
+// }
+#define CHECK_CONSTEXPR(x, out, dummy) \
+ (UNLIKELY(!(x))) \
+ ? (LOG(FATAL) << "Check failed: " << #x out, dummy) \
+ :
+
+// DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally
+// CHECK should be used unless profiling identifies a CHECK as being in
+// performance critical code.
+#if defined(NDEBUG)
+static constexpr bool kEnableDChecks = false;
+#else
+static constexpr bool kEnableDChecks = true;
+#endif
+
+#define DCHECK(x) \
+ if (::android::base::kEnableDChecks) CHECK(x)
+#define DCHECK_EQ(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_EQ(x, y)
+#define DCHECK_NE(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_NE(x, y)
+#define DCHECK_LE(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_LE(x, y)
+#define DCHECK_LT(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_LT(x, y)
+#define DCHECK_GE(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_GE(x, y)
+#define DCHECK_GT(x, y) \
+ if (::android::base::kEnableDChecks) CHECK_GT(x, y)
+#define DCHECK_STREQ(s1, s2) \
+ if (::android::base::kEnableDChecks) CHECK_STREQ(s1, s2)
+#define DCHECK_STRNE(s1, s2) \
+ if (::android::base::kEnableDChecks) CHECK_STRNE(s1, s2)
+#if defined(NDEBUG)
+#define DCHECK_CONSTEXPR(x, out, dummy)
+#else
+#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
+#endif
+
+// Temporary class created to evaluate the LHS and RHS, used with
+// MakeEagerEvaluator to infer the types of LHS and RHS.
+template <typename LHS, typename RHS>
+struct EagerEvaluator {
+ constexpr EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) {
+ }
+ LHS lhs;
+ RHS rhs;
+};
+
+// Helper function for CHECK_xx.
+template <typename LHS, typename RHS>
+constexpr EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
+ return EagerEvaluator<LHS, RHS>(lhs, rhs);
+}
+
+// Explicitly instantiate EagerEvalue for pointers so that char*s aren't treated
+// as strings. To compare strings use CHECK_STREQ and CHECK_STRNE. We rely on
+// signed/unsigned warnings to protect you against combinations not explicitly
+// listed below.
+#define EAGER_PTR_EVALUATOR(T1, T2) \
+ template <> \
+ struct EagerEvaluator<T1, T2> { \
+ EagerEvaluator(T1 l, T2 r) \
+ : lhs(reinterpret_cast<const void*>(l)), \
+ rhs(reinterpret_cast<const void*>(r)) { \
+ } \
+ const void* lhs; \
+ const void* rhs; \
+ }
+EAGER_PTR_EVALUATOR(const char*, const char*);
+EAGER_PTR_EVALUATOR(const char*, char*);
+EAGER_PTR_EVALUATOR(char*, const char*);
+EAGER_PTR_EVALUATOR(char*, char*);
+EAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*);
+EAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*);
+EAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*);
+EAGER_PTR_EVALUATOR(unsigned char*, unsigned char*);
+EAGER_PTR_EVALUATOR(const signed char*, const signed char*);
+EAGER_PTR_EVALUATOR(const signed char*, signed char*);
+EAGER_PTR_EVALUATOR(signed char*, const signed char*);
+EAGER_PTR_EVALUATOR(signed char*, signed char*);
+
+// Data for the log message, not stored in LogMessage to avoid increasing the
+// stack size.
+class LogMessageData;
+
+// A LogMessage is a temporarily scoped object used by LOG and the unlikely part
+// of a CHECK. The destructor will abort if the severity is FATAL.
+class LogMessage {
+ public:
+ LogMessage(const char* file, unsigned int line, LogId id,
+ LogSeverity severity, int error);
+
+ ~LogMessage();
+
+ // Returns the stream associated with the message, the LogMessage performs
+ // output when it goes out of scope.
+ std::ostream& stream();
+
+ // The routine that performs the actual logging.
+ static void LogLine(const char* file, unsigned int line, LogId id,
+ LogSeverity severity, const char* msg);
+
+ private:
+ const std::unique_ptr<LogMessageData> data_;
+
+ DISALLOW_COPY_AND_ASSIGN(LogMessage);
+};
+
+// Get the minimum severity level for logging.
+LogSeverity GetMinimumLogSeverity();
+
+// Set the minimum severity level for logging, returning the old severity.
+LogSeverity SetMinimumLogSeverity(LogSeverity new_severity);
+
+// Allows to temporarily change the minimum severity level for logging.
+class ScopedLogSeverity {
+ public:
+ explicit ScopedLogSeverity(LogSeverity level);
+ ~ScopedLogSeverity();
+
+ private:
+ LogSeverity old_;
+};
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_LOGGING_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/macros.h
^
|
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_MACROS_H
+#define ANDROID_BASE_MACROS_H
+
+#include <stddef.h> // for size_t
+#include <unistd.h> // for TEMP_FAILURE_RETRY
+
+// bionic and glibc both have TEMP_FAILURE_RETRY, but eg Mac OS' libc doesn't.
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ decltype(exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; \
+ })
+#endif
+
+// A macro to disallow the copy constructor and operator= functions
+// This must be placed in the private: declarations for a class.
+//
+// For disallowing only assign or copy, delete the relevant operator or
+// constructor, for example:
+// void operator=(const TypeName&) = delete;
+// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
+// semantically, one should either use disallow both or neither. Try to
+// avoid these in new code.
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName() = delete; \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example. If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function. In these rare
+// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is
+// due to a limitation in C++'s template system. The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char(&ArraySizeHelper(T(&array)[N]))[N]; // NOLINT(readability/casting)
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
+// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
+// but can be used on anonymous types or types defined inside
+// functions. It's less safe than arraysize as it accepts some
+// (although not all) pointers. Therefore, you should use arraysize
+// whenever possible.
+//
+// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type
+// size_t.
+//
+// ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error
+//
+// "warning: division by zero in ..."
+//
+// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer.
+// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element). If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array. Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size. Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+#define ARRAYSIZE_UNSAFE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+// Changing this definition will cause you a lot of pain. A majority of
+// vendor code defines LIKELY and UNLIKELY this way, and includes
+// this header through an indirect path.
+#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
+#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
+
+#define WARN_UNUSED __attribute__((warn_unused_result))
+
+// A deprecated function to call to create a false use of the parameter, for
+// example:
+// int foo(int x) { UNUSED(x); return 10; }
+// to avoid compiler warnings. Going forward we prefer ATTRIBUTE_UNUSED.
+template <typename... T>
+void UNUSED(const T&...) {
+}
+
+// An attribute to place on a parameter to a function, for example:
+// int foo(int x ATTRIBUTE_UNUSED) { return 10; }
+// to avoid compiler warnings.
+#define ATTRIBUTE_UNUSED __attribute__((__unused__))
+
+// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
+// between switch labels:
+// switch (x) {
+// case 40:
+// case 41:
+// if (truth_is_out_there) {
+// ++x;
+// FALLTHROUGH_INTENDED; // Use instead of/along with annotations in
+// // comments.
+// } else {
+// return x;
+// }
+// case 42:
+// ...
+//
+// As shown in the example above, the FALLTHROUGH_INTENDED macro should be
+// followed by a semicolon. It is designed to mimic control-flow statements
+// like 'break;', so it can be placed in most places where 'break;' can, but
+// only if there are no statements on the execution path between it and the
+// next switch label.
+//
+// When compiled with clang, the FALLTHROUGH_INTENDED macro is expanded to
+// [[clang::fallthrough]] attribute, which is analysed when performing switch
+// labels fall-through diagnostic ('-Wimplicit-fallthrough'). See clang
+// documentation on language extensions for details:
+// http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
+//
+// When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
+// effect on diagnostics.
+//
+// In either case this macro has no effect on runtime behavior and performance
+// of code.
+#if defined(__clang__) && defined(__has_warning)
+#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
+#define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT
+#endif
+#endif
+
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED \
+ do { \
+ } while (0)
+#endif
+
+#endif // ANDROID_BASE_MACROS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/memory.h
^
|
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_MEMORY_H
+#define ANDROID_BASE_MEMORY_H
+
+namespace android {
+namespace base {
+
+// Use memcpy for access to unaligned data on targets with alignment
+// restrictions. The compiler will generate appropriate code to access these
+// structures without generating alignment exceptions.
+template <typename T>
+static inline T get_unaligned(const void* address) {
+ T result;
+ memcpy(&result, address, sizeof(T));
+ return result;
+}
+
+template <typename T>
+static inline void put_unaligned(void* address, T v) {
+ memcpy(address, &v, sizeof(T));
+}
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_MEMORY_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/parsedouble.h
^
|
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_BASE_PARSEDOUBLE_H
+#define ANDROID_BASE_PARSEDOUBLE_H
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <limits>
+
+namespace android {
+namespace base {
+
+// Parse double value in the string 's' and sets 'out' to that value.
+// Optionally allows the caller to define a 'min' and 'max' beyond which
+// otherwise valid values will be rejected. Returns boolean success.
+static inline bool ParseDouble(const char* s, double* out,
+ double min = std::numeric_limits<double>::lowest(),
+ double max = std::numeric_limits<double>::max()) {
+ errno = 0;
+ char* end;
+ double result = strtod(s, &end);
+ if (errno != 0 || s == end || *end != '\0') {
+ return false;
+ }
+ if (result < min || max < result) {
+ return false;
+ }
+ *out = result;
+ return true;
+}
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_PARSEDOUBLE_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/parseint.h
^
|
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_PARSEINT_H
+#define ANDROID_BASE_PARSEINT_H
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <limits>
+#include <string>
+
+namespace android {
+namespace base {
+
+// Parses the unsigned decimal integer in the string 's' and sets 'out' to
+// that value. Optionally allows the caller to define a 'max' beyond which
+// otherwise valid values will be rejected. Returns boolean success; 'out'
+// is untouched if parsing fails.
+template <typename T>
+bool ParseUint(const char* s, T* out,
+ T max = std::numeric_limits<T>::max()) {
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
+ errno = 0;
+ char* end;
+ unsigned long long int result = strtoull(s, &end, base);
+ if (errno != 0 || s == end || *end != '\0') {
+ return false;
+ }
+ if (max < result) {
+ return false;
+ }
+ *out = static_cast<T>(result);
+ return true;
+}
+
+// TODO: string_view
+template <typename T>
+bool ParseUint(const std::string& s, T* out,
+ T max = std::numeric_limits<T>::max()) {
+ return ParseUint(s.c_str(), out, max);
+}
+
+// Parses the signed decimal integer in the string 's' and sets 'out' to
+// that value. Optionally allows the caller to define a 'min' and 'max
+// beyond which otherwise valid values will be rejected. Returns boolean
+// success; 'out' is untouched if parsing fails.
+template <typename T>
+bool ParseInt(const char* s, T* out,
+ T min = std::numeric_limits<T>::min(),
+ T max = std::numeric_limits<T>::max()) {
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
+ errno = 0;
+ char* end;
+ long long int result = strtoll(s, &end, base);
+ if (errno != 0 || s == end || *end != '\0') {
+ return false;
+ }
+ if (result < min || max < result) {
+ return false;
+ }
+ *out = static_cast<T>(result);
+ return true;
+}
+
+// TODO: string_view
+template <typename T>
+bool ParseInt(const std::string& s, T* out,
+ T min = std::numeric_limits<T>::min(),
+ T max = std::numeric_limits<T>::max()) {
+ return ParseInt(s.c_str(), out, min, max);
+}
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_PARSEINT_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/parsenetaddress.h
^
|
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_BASE_PARSENETADDRESS_H
+#define ANDROID_BASE_PARSENETADDRESS_H
+
+#include <string>
+
+namespace android {
+namespace base {
+
+// Parses |address| into |host| and |port|.
+//
+// If |address| doesn't contain a port number, the default value is taken from
+// |port|. If |canonical_address| is non-null it will be set to "host:port" or
+// "[host]:port" as appropriate.
+//
+// On failure, returns false and fills |error|.
+bool ParseNetAddress(const std::string& address, std::string* host, int* port,
+ std::string* canonical_address, std::string* error);
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_PARSENETADDRESS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/properties.h
^
|
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_BASE_PROPERTIES_H
+#define ANDROID_BASE_PROPERTIES_H
+
+#include <sys/cdefs.h>
+
+#if !defined(__BIONIC__)
+#error Only bionic supports system properties.
+#endif
+
+#include <chrono>
+#include <limits>
+#include <string>
+
+namespace android {
+namespace base {
+
+// Returns the current value of the system property `key`,
+// or `default_value` if the property is empty or doesn't exist.
+std::string GetProperty(const std::string& key, const std::string& default_value);
+
+// Returns true if the system property `key` has the value "1", "y", "yes", "on", or "true",
+// false for "0", "n", "no", "off", or "false", or `default_value` otherwise.
+bool GetBoolProperty(const std::string& key, bool default_value);
+
+// Returns the signed integer corresponding to the system property `key`.
+// If the property is empty, doesn't exist, doesn't have an integer value, or is outside
+// the optional bounds, returns `default_value`.
+template <typename T> T GetIntProperty(const std::string& key,
+ T default_value,
+ T min = std::numeric_limits<T>::min(),
+ T max = std::numeric_limits<T>::max());
+
+// Returns the unsigned integer corresponding to the system property `key`.
+// If the property is empty, doesn't exist, doesn't have an integer value, or is outside
+// the optional bound, returns `default_value`.
+template <typename T> T GetUintProperty(const std::string& key,
+ T default_value,
+ T max = std::numeric_limits<T>::max());
+
+// Sets the system property `key` to `value`.
+// Note that system property setting is inherently asynchronous so a return value of `true`
+// isn't particularly meaningful, and immediately reading back the value won't necessarily
+// tell you whether or not your call succeeded. A `false` return value definitely means failure.
+bool SetProperty(const std::string& key, const std::string& value);
+
+// Waits for the system property `key` to have the value `expected_value`.
+// Times out after `relative_timeout`.
+// Returns true on success, false on timeout.
+bool WaitForProperty(const std::string& key,
+ const std::string& expected_value,
+ std::chrono::milliseconds relative_timeout);
+
+// Waits for the system property `key` to be created.
+// Times out after `relative_timeout`.
+// Returns true on success, false on timeout.
+bool WaitForPropertyCreation(const std::string& key,
+ std::chrono::milliseconds relative_timeout);
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_PROPERTIES_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/quick_exit.h
^
|
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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 <stdlib.h>
+
+// Provide emulation for at_quick_exit/quick_exit on platforms that don't have it.
+namespace android {
+namespace base {
+
+// Bionic and glibc have quick_exit, Darwin and Windows don't.
+#if !defined(__linux__)
+ void quick_exit(int exit_code) __attribute__((noreturn));
+ int at_quick_exit(void (*func)());
+#else
+ using ::at_quick_exit;
+ using ::quick_exit;
+#endif
+}
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/scopeguard.h
^
|
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+#ifndef ANDROID_BASE_SCOPEGUARD_H
+#define ANDROID_BASE_SCOPEGUARD_H
+#include <utility> // for std::move
+namespace android {
+namespace base {
+template <typename F>
+class ScopeGuard {
+ public:
+ ScopeGuard(F f) : f_(f), active_(true) {}
+ ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) {
+ that.active_ = false;
+ }
+ ~ScopeGuard() {
+ if (active_) f_();
+ }
+ ScopeGuard() = delete;
+ ScopeGuard(const ScopeGuard&) = delete;
+ void operator=(const ScopeGuard&) = delete;
+ void operator=(ScopeGuard&& that) = delete;
+ void Disable() { active_ = false; }
+ bool active() const { return active_; }
+ private:
+ F f_;
+ bool active_;
+};
+template <typename T>
+ScopeGuard<T> make_scope_guard(T f) {
+ return ScopeGuard<T>(f);
+}
+} // namespace base
+} // namespace android
+#endif // ANDROID_BASE_SCOPEGUARD_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/stringprintf.h
^
|
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef ANDROID_BASE_STRINGPRINTF_H
+#define ANDROID_BASE_STRINGPRINTF_H
+
+#include <stdarg.h>
+#include <string>
+
+namespace android {
+namespace base {
+
+// These printf-like functions are implemented in terms of vsnprintf, so they
+// use the same attribute for compile-time format string checking. On Windows,
+// if the mingw version of vsnprintf is used, use `gnu_printf' which allows z
+// in %zd and PRIu64 (and related) to be recognized by the compile-time
+// checking.
+#define FORMAT_ARCHETYPE __printf__
+#ifdef __USE_MINGW_ANSI_STDIO
+#if __USE_MINGW_ANSI_STDIO
+#undef FORMAT_ARCHETYPE
+#define FORMAT_ARCHETYPE gnu_printf
+#endif
+#endif
+
+// Returns a string corresponding to printf-like formatting of the arguments.
+std::string StringPrintf(const char* fmt, ...)
+ __attribute__((__format__(FORMAT_ARCHETYPE, 1, 2)));
+
+// Appends a printf-like formatting of the arguments to 'dst'.
+void StringAppendF(std::string* dst, const char* fmt, ...)
+ __attribute__((__format__(FORMAT_ARCHETYPE, 2, 3)));
+
+// Appends a printf-like formatting of the arguments to 'dst'.
+void StringAppendV(std::string* dst, const char* format, va_list ap)
+ __attribute__((__format__(FORMAT_ARCHETYPE, 2, 0)));
+
+#undef FORMAT_ARCHETYPE
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_STRINGPRINTF_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/strings.h
^
|
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_STRINGS_H
+#define ANDROID_BASE_STRINGS_H
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace base {
+
+// Splits a string into a vector of strings.
+//
+// The string is split at each occurrence of a character in delimiters.
+//
+// The empty string is not a valid delimiter list.
+std::vector<std::string> Split(const std::string& s,
+ const std::string& delimiters);
+
+// Trims whitespace off both ends of the given string.
+std::string Trim(const std::string& s);
+
+// Joins a container of things into a single string, using the given separator.
+template <typename ContainerT, typename SeparatorT>
+std::string Join(const ContainerT& things, SeparatorT separator) {
+ if (things.empty()) {
+ return "";
+ }
+
+ std::ostringstream result;
+ result << *things.begin();
+ for (auto it = std::next(things.begin()); it != things.end(); ++it) {
+ result << separator << *it;
+ }
+ return result.str();
+}
+
+// We instantiate the common cases in strings.cpp.
+extern template std::string Join(const std::vector<std::string>&, char);
+extern template std::string Join(const std::vector<const char*>&, char);
+extern template std::string Join(const std::vector<std::string>&, const std::string&);
+extern template std::string Join(const std::vector<const char*>&, const std::string&);
+
+// Tests whether 's' starts with 'prefix'.
+bool StartsWith(const std::string& s, const char* prefix);
+bool StartsWithIgnoreCase(const std::string& s, const char* prefix);
+
+// Tests whether 's' ends with 'suffix'.
+bool EndsWith(const std::string& s, const char* suffix);
+bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
+
+// Tests whether 'lhs' equals 'rhs', ignoring case.
+bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs);
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_STRINGS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/test_utils.h
^
|
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_TEST_UTILS_H
+#define ANDROID_BASE_TEST_UTILS_H
+
+#include <string>
+
+#include <android-base/macros.h>
+
+class TemporaryFile {
+ public:
+ TemporaryFile();
+ ~TemporaryFile();
+
+ int fd;
+ char path[1024];
+
+ private:
+ void init(const std::string& tmp_dir);
+
+ DISALLOW_COPY_AND_ASSIGN(TemporaryFile);
+};
+
+class TemporaryDir {
+ public:
+ TemporaryDir();
+ ~TemporaryDir();
+
+ char path[1024];
+
+ private:
+ bool init(const std::string& tmp_dir);
+
+ DISALLOW_COPY_AND_ASSIGN(TemporaryDir);
+};
+
+class CapturedStderr {
+ public:
+ CapturedStderr();
+ ~CapturedStderr();
+
+ int fd() const;
+
+ private:
+ void init();
+ void reset();
+
+ TemporaryFile temp_file_;
+ int old_stderr_;
+
+ DISALLOW_COPY_AND_ASSIGN(CapturedStderr);
+};
+
+#endif // ANDROID_BASE_TEST_UTILS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/thread_annotations.h
^
|
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_BASE_THREAD_ANNOTATIONS_H
+#define ANDROID_BASE_THREAD_ANNOTATIONS_H
+
+#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__)
+#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
+#else
+#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
+#endif
+
+#define CAPABILITY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
+
+#define SCOPED_CAPABILITY \
+ THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define SHARED_CAPABILITY(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(shared_capability(__VA_ARGS__))
+
+#define GUARDED_BY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+
+#define PT_GUARDED_BY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+
+#define ACQUIRED_BEFORE(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
+
+#define ACQUIRED_AFTER(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
+
+#define REQUIRES(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
+
+#define REQUIRES_SHARED(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
+
+#define ACQUIRE(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
+
+#define ACQUIRE_SHARED(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
+
+#define RELEASE(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
+
+#define RELEASE_SHARED(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
+
+#define TRY_ACQUIRE_SHARED(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
+
+#define EXCLUDES(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
+
+#define ASSERT_CAPABILITY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
+
+#define ASSERT_SHARED_CAPABILITY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
+
+#define RETURN_CAPABILITY(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define EXCLUSIVE_LOCK_FUNCTION(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
+
+#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
+
+#define SHARED_LOCK_FUNCTION(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
+
+#define SHARED_TRYLOCK_FUNCTION(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
+
+#define UNLOCK_FUNCTION(...) \
+ THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
+
+#define SCOPED_LOCKABLE \
+ THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define LOCK_RETURNED(x) \
+ THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define NO_THREAD_SAFETY_ANALYSIS \
+ THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+
+#endif // ANDROID_BASE_THREAD_ANNOTATIONS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/unique_fd.h
^
|
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_UNIQUE_FD_H
+#define ANDROID_BASE_UNIQUE_FD_H
+
+#include <unistd.h>
+
+// DO NOT INCLUDE OTHER LIBBASE HEADERS!
+// This file gets used in libbinder, and libbinder is used everywhere.
+// Including other headers from libbase frequently results in inclusion of
+// android-base/macros.h, which causes macro collisions.
+
+// Container for a file descriptor that automatically closes the descriptor as
+// it goes out of scope.
+//
+// unique_fd ufd(open("/some/path", "r"));
+// if (ufd.get() == -1) return error;
+//
+// // Do something useful, possibly including 'return'.
+//
+// return 0; // Descriptor is closed for you.
+//
+// unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help
+// you find this class if you're searching for one of those names.
+namespace android {
+namespace base {
+
+struct DefaultCloser {
+ static void Close(int fd) {
+ // Even if close(2) fails with EINTR, the fd will have been closed.
+ // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone
+ // else's fd.
+ // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+ ::close(fd);
+ }
+};
+
+template <typename Closer>
+class unique_fd_impl final {
+ public:
+ unique_fd_impl() : value_(-1) {}
+
+ explicit unique_fd_impl(int value) : value_(value) {}
+ ~unique_fd_impl() { reset(); }
+
+ unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {}
+ unique_fd_impl& operator=(unique_fd_impl&& s) {
+ reset(s.release());
+ return *this;
+ }
+
+ void reset(int new_value = -1) {
+ if (value_ != -1) {
+ Closer::Close(value_);
+ }
+ value_ = new_value;
+ }
+
+ int get() const { return value_; }
+ operator int() const { return get(); }
+
+ int release() __attribute__((warn_unused_result)) {
+ int ret = value_;
+ value_ = -1;
+ return ret;
+ }
+
+ private:
+ int value_;
+
+ unique_fd_impl(const unique_fd_impl&);
+ void operator=(const unique_fd_impl&);
+};
+
+using unique_fd = unique_fd_impl<DefaultCloser>;
+
+} // namespace base
+} // namespace android
+
+template <typename T>
+int close(const android::base::unique_fd_impl<T>&)
+#if defined(__clang__)
+ __attribute__((__unavailable__(
+#else
+ __attribute__((__error__(
+#endif
+ "close called on unique_fd"
+ )));
+
+#endif // ANDROID_BASE_UNIQUE_FD_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android-base/utf8.h
^
|
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_BASE_UTF8_H
+#define ANDROID_BASE_UTF8_H
+
+#ifdef _WIN32
+#include <string>
+#else
+// Bring in prototypes for standard APIs so that we can import them into the utf8 namespace.
+#include <fcntl.h> // open
+#include <unistd.h> // unlink
+#endif
+
+namespace android {
+namespace base {
+
+// Only available on Windows because this is only needed on Windows.
+#ifdef _WIN32
+// Convert size number of UTF-16 wchar_t's to UTF-8. Returns whether the
+// conversion was done successfully.
+bool WideToUTF8(const wchar_t* utf16, const size_t size, std::string* utf8);
+
+// Convert a NULL-terminated string of UTF-16 characters to UTF-8. Returns
+// whether the conversion was done successfully.
+bool WideToUTF8(const wchar_t* utf16, std::string* utf8);
+
+// Convert a UTF-16 std::wstring (including any embedded NULL characters) to
+// UTF-8. Returns whether the conversion was done successfully.
+bool WideToUTF8(const std::wstring& utf16, std::string* utf8);
+
+// Convert size number of UTF-8 char's to UTF-16. Returns whether the conversion
+// was done successfully.
+bool UTF8ToWide(const char* utf8, const size_t size, std::wstring* utf16);
+
+// Convert a NULL-terminated string of UTF-8 characters to UTF-16. Returns
+// whether the conversion was done successfully.
+bool UTF8ToWide(const char* utf8, std::wstring* utf16);
+
+// Convert a UTF-8 std::string (including any embedded NULL characters) to
+// UTF-16. Returns whether the conversion was done successfully.
+bool UTF8ToWide(const std::string& utf8, std::wstring* utf16);
+#endif
+
+// The functions in the utf8 namespace take UTF-8 strings. For Windows, these
+// are wrappers, for non-Windows these just expose existing APIs. To call these
+// functions, use:
+//
+// // anonymous namespace to avoid conflict with existing open(), unlink(), etc.
+// namespace {
+// // Import functions into anonymous namespace.
+// using namespace android::base::utf8;
+//
+// void SomeFunction(const char* name) {
+// int fd = open(name, ...); // Calls android::base::utf8::open().
+// ...
+// unlink(name); // Calls android::base::utf8::unlink().
+// }
+// }
+namespace utf8 {
+
+#ifdef _WIN32
+int open(const char* name, int flags, ...);
+int unlink(const char* name);
+#else
+using ::open;
+using ::unlink;
+#endif
+
+} // namespace utf8
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_UTF8_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android/api-level.h
^
|
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_API_LEVEL_H
+#define ANDROID_API_LEVEL_H
+
+#include <sys/cdefs.h>
+
+/*
+ * Magic version number for a current development build, which has
+ * not yet turned into an official release.
+ */
+#ifndef __ANDROID_API_FUTURE__
+#define __ANDROID_API_FUTURE__ 10000
+#endif
+
+#ifndef __ANDROID_API__
+#define __ANDROID_API__ __ANDROID_API_FUTURE__
+#endif
+
+#define __ANDROID_API_G__ 9
+#define __ANDROID_API_I__ 14
+#define __ANDROID_API_J__ 16
+#define __ANDROID_API_J_MR1__ 17
+#define __ANDROID_API_J_MR2__ 18
+#define __ANDROID_API_K__ 19
+#define __ANDROID_API_L__ 21
+#define __ANDROID_API_L_MR1__ 22
+#define __ANDROID_API_M__ 23
+#define __ANDROID_API_N__ 24
+#define __ANDROID_API_N_MR1__ 25
+#define __ANDROID_API_O__ 26
+#define __ANDROID_API_O_MR1__ 27
+
+#endif /* ANDROID_API_LEVEL_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android/dlext.h
^
|
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef __ANDROID_DLEXT_H__
+#define __ANDROID_DLEXT_H__
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h> /* for off64_t */
+
+__BEGIN_DECLS
+
+/* bitfield definitions for android_dlextinfo.flags */
+enum {
+ /* When set, the reserved_addr and reserved_size fields must point to an
+ * already-reserved region of address space which will be used to load the
+ * library if it fits. If the reserved region is not large enough, the load
+ * will fail.
+ */
+ ANDROID_DLEXT_RESERVED_ADDRESS = 0x1,
+
+ /* As DLEXT_RESERVED_ADDRESS, but if the reserved region is not large enough,
+ * the linker will choose an available address instead.
+ */
+ ANDROID_DLEXT_RESERVED_ADDRESS_HINT = 0x2,
+
+ /* When set, write the GNU RELRO section of the mapped library to relro_fd
+ * after relocation has been performed, to allow it to be reused by another
+ * process loading the same library at the same address. This implies
+ * ANDROID_DLEXT_USE_RELRO.
+ */
+ ANDROID_DLEXT_WRITE_RELRO = 0x4,
+
+ /* When set, compare the GNU RELRO section of the mapped library to relro_fd
+ * after relocation has been performed, and replace any relocated pages that
+ * are identical with a version mapped from the file.
+ */
+ ANDROID_DLEXT_USE_RELRO = 0x8,
+
+ /* Instruct dlopen to use library_fd instead of opening file by name.
+ * The filename parameter is still used to identify the library.
+ */
+ ANDROID_DLEXT_USE_LIBRARY_FD = 0x10,
+
+ /* If opening a library using library_fd read it starting at library_fd_offset.
+ * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
+ */
+ ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET = 0x20,
+
+ /* When set, do not check if the library has already been loaded by file stat(2)s.
+ *
+ * This flag allows forced loading of the library in the case when for some
+ * reason multiple ELF files share the same filename (because the already-loaded
+ * library has been removed and overwritten, for example).
+ *
+ * Note that if the library has the same dt_soname as an old one and some other
+ * library has the soname in DT_NEEDED list, the first one will be used to resolve any
+ * dependencies.
+ */
+ ANDROID_DLEXT_FORCE_LOAD = 0x40,
+
+ /* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,
+ * the dynamic linker will load it at that address.
+ *
+ * This flag is for ART internal use only.
+ */
+ ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
+
+ /* Instructs dlopen to load the library at the address specified by reserved_addr.
+ *
+ * The difference between ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS and ANDROID_DLEXT_RESERVED_ADDRESS
+ * is that for ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS the linker reserves memory at reserved_addr
+ * whereas for ANDROID_DLEXT_RESERVED_ADDRESS the linker relies on the caller to reserve the memory.
+ *
+ * This flag can be used with ANDROID_DLEXT_FORCE_FIXED_VADDR; when ANDROID_DLEXT_FORCE_FIXED_VADDR
+ * is set and load_bias is not 0 (load_bias is min(p_vaddr) of PT_LOAD segments) this flag is ignored.
+ * This is implemented this way because the linker has to pick one address over the other and this
+ * way is more convenient for art. Note that ANDROID_DLEXT_FORCE_FIXED_VADDR does not generate
+ * an error when min(p_vaddr) is 0.
+ *
+ * Cannot be used with ANDROID_DLEXT_RESERVED_ADDRESS or ANDROID_DLEXT_RESERVED_ADDRESS_HINT.
+ *
+ * This flag is for ART internal use only.
+ */
+ ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
+
+ /* This flag used to load library in a different namespace. The namespace is
+ * specified in library_namespace.
+ */
+ ANDROID_DLEXT_USE_NAMESPACE = 0x200,
+
+ /* Mask of valid bits */
+ ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
+ ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
+ ANDROID_DLEXT_WRITE_RELRO |
+ ANDROID_DLEXT_USE_RELRO |
+ ANDROID_DLEXT_USE_LIBRARY_FD |
+ ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
+ ANDROID_DLEXT_FORCE_LOAD |
+ ANDROID_DLEXT_FORCE_FIXED_VADDR |
+ ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS |
+ ANDROID_DLEXT_USE_NAMESPACE,
+};
+
+struct android_namespace_t;
+
+typedef struct {
+ uint64_t flags;
+ void* reserved_addr;
+ size_t reserved_size;
+ int relro_fd;
+ int library_fd;
+ off64_t library_fd_offset;
+ struct android_namespace_t* library_namespace;
+} android_dlextinfo;
+
+void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);
+
+__END_DECLS
+
+#endif /* __ANDROID_DLEXT_H__ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/android/versioning.h
^
|
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_VERSIONING_H
+#define ANDROID_VERSIONING_H
+
+#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
+#define __INTRODUCED_IN_FUTURE __attribute__((annotate("introduced_in_future")))
+#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
+#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
+#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
+#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
+#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" #api_level)))
+#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" #api_level)))
+#define __INTRODUCED_IN_MIPS(api_level) __attribute__((annotate("introduced_in_mips=" #api_level)))
+
+#define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
+
+#endif /* ANDROID_VERSIONING_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/dlfcn.h
^
|
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __DLFCN_H__
+#define __DLFCN_H__
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#if defined(__cplusplus)
+#define __BIONIC_CAST(_k,_t,_v) (_k<_t>(_v))
+#else
+#define __BIONIC_CAST(_k,_t,_v) ((_t) (_v))
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
+#endif
+
+typedef struct {
+ /* Pathname of shared object that contains address. */
+ const char* dli_fname;
+ /* Address at which shared object is loaded. */
+ void* dli_fbase;
+ /* Name of nearest symbol with address lower than addr. */
+ const char* dli_sname;
+ /* Exact address of symbol named in dli_sname. */
+ void* dli_saddr;
+} Dl_info;
+
+void* dlopen(const char* filename, int flag);
+int dlclose(void* handle) __nonnull((1));
+char* dlerror(void);
+void* dlsym(void* handle, const char* symbol) __nonnull((2));
+void* dlvsym(void* handle, const char* symbol, const char* version) __nonnull((2, 3));
+int dladdr(const void* addr, Dl_info* info) __nonnull((2));
+
+#define RTLD_LOCAL 0
+#define RTLD_LAZY 0x00001
+#define RTLD_NOW 0x00002
+#define RTLD_NOLOAD 0x00004
+#define RTLD_GLOBAL 0x00100
+#define RTLD_NODELETE 0x01000
+
+#if !defined(__LP64__)
+/* LP32 is broken for historical reasons. */
+#undef RTLD_NOW
+#define RTLD_NOW 0x00000
+#undef RTLD_GLOBAL
+#define RTLD_GLOBAL 0x00002
+#endif
+
+#if defined (__LP64__)
+#define RTLD_DEFAULT __BIONIC_CAST(reinterpret_cast, void*, 0)
+#define RTLD_NEXT __BIONIC_CAST(reinterpret_cast, void*, -1L)
+#else
+#define RTLD_DEFAULT __BIONIC_CAST(reinterpret_cast, void*, 0xffffffff)
+#define RTLD_NEXT __BIONIC_CAST(reinterpret_cast, void*, 0xfffffffe)
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+__END_DECLS
+
+#endif /* __DLFCN_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/link.h
^
|
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _LINK_H_
+#define _LINK_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <elf.h>
+
+__BEGIN_DECLS
+
+#if defined(__LP64__)
+#define ElfW(type) Elf64_ ## type
+#else
+#define ElfW(type) Elf32_ ## type
+#endif
+
+struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr;
+ const char* dlpi_name;
+ const ElfW(Phdr)* dlpi_phdr;
+ ElfW(Half) dlpi_phnum;
+};
+
+#if defined(__arm__)
+int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);
+#else
+int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);
+#endif
+
+#ifdef __arm__
+typedef uintptr_t _Unwind_Ptr;
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
+#endif
+
+/* Used by the dynamic linker to communicate with the debugger. */
+struct link_map {
+ ElfW(Addr) l_addr;
+ char* l_name;
+ ElfW(Dyn)* l_ld;
+ struct link_map* l_next;
+ struct link_map* l_prev;
+};
+
+/* Used by the dynamic linker to communicate with the debugger. */
+struct r_debug {
+ int32_t r_version;
+ struct link_map* r_map;
+ ElfW(Addr) r_brk;
+ enum {
+ RT_CONSISTENT,
+ RT_ADD,
+ RT_DELETE
+ } r_state;
+ ElfW(Addr) r_ldbase;
+};
+
+__END_DECLS
+
+#endif /* _LINK_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/stdatomic.h
^
|
@@ -0,0 +1,546 @@
+/*-
+ * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
+ * David Chisnall <theraven@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _STDATOMIC_H_
+#define _STDATOMIC_H_
+
+#include <sys/cdefs.h>
+
+#if defined(__cplusplus) && __cplusplus >= 201103L && defined(_USING_LIBCXX)
+# ifdef __clang__
+# if __has_feature(cxx_atomic)
+# define _STDATOMIC_HAVE_ATOMIC
+# endif
+# else /* gcc */
+# define _STDATOMIC_HAVE_ATOMIC
+# endif
+#endif
+
+#ifdef _STDATOMIC_HAVE_ATOMIC
+
+/* We have a usable C++ <atomic>; use it instead. */
+
+#include <atomic>
+
+#undef _Atomic
+ /* Also defined by <atomic> for gcc. But not used in macros. */
+ /* Also a clang intrinsic. */
+ /* Should not be used by client code before this file is */
+ /* included. The definitions in <atomic> themselves see */
+ /* the old definition, as they should. */
+ /* Client code sees the following definition. */
+
+#define _Atomic(t) std::atomic<t>
+
+using std::atomic_is_lock_free;
+using std::atomic_init;
+using std::atomic_store;
+using std::atomic_store_explicit;
+using std::atomic_load;
+using std::atomic_load_explicit;
+using std::atomic_exchange;
+using std::atomic_exchange_explicit;
+using std::atomic_compare_exchange_strong;
+using std::atomic_compare_exchange_strong_explicit;
+using std::atomic_compare_exchange_weak;
+using std::atomic_compare_exchange_weak_explicit;
+using std::atomic_fetch_add;
+using std::atomic_fetch_add_explicit;
+using std::atomic_fetch_sub;
+using std::atomic_fetch_sub_explicit;
+using std::atomic_fetch_or;
+using std::atomic_fetch_or_explicit;
+using std::atomic_fetch_xor;
+using std::atomic_fetch_xor_explicit;
+using std::atomic_fetch_and;
+using std::atomic_fetch_and_explicit;
+using std::atomic_thread_fence;
+using std::atomic_signal_fence;
+
+using std::memory_order;
+using std::memory_order_relaxed;
+using std::memory_order_consume;
+using std::memory_order_acquire;
+using std::memory_order_release;
+using std::memory_order_acq_rel;
+using std::memory_order_seq_cst;
+
+using std::atomic_bool;
+using std::atomic_char;
+using std::atomic_schar;
+using std::atomic_uchar;
+using std::atomic_short;
+using std::atomic_ushort;
+using std::atomic_int;
+using std::atomic_uint;
+using std::atomic_long;
+using std::atomic_ulong;
+using std::atomic_llong;
+using std::atomic_ullong;
+using std::atomic_char16_t;
+using std::atomic_char32_t;
+using std::atomic_wchar_t;
+using std::atomic_int_least8_t;
+using std::atomic_uint_least8_t;
+using std::atomic_int_least16_t;
+using std::atomic_uint_least16_t;
+using std::atomic_int_least32_t;
+using std::atomic_uint_least32_t;
+using std::atomic_int_least64_t;
+using std::atomic_uint_least64_t;
+using std::atomic_int_fast8_t;
+using std::atomic_uint_fast8_t;
+using std::atomic_int_fast16_t;
+using std::atomic_uint_fast16_t;
+using std::atomic_int_fast32_t;
+using std::atomic_uint_fast32_t;
+using std::atomic_int_fast64_t;
+using std::atomic_uint_fast64_t;
+using std::atomic_intptr_t;
+using std::atomic_uintptr_t;
+using std::atomic_size_t;
+using std::atomic_ptrdiff_t;
+using std::atomic_intmax_t;
+using std::atomic_uintmax_t;
+
+#else /* <atomic> unavailable, possibly because this is C, not C++ */
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+/*
+ * C: Do it ourselves.
+ * Note that the runtime representation defined here should be compatible
+ * with the C++ one, i.e. an _Atomic(T) needs to contain the same
+ * bits as a T.
+ */
+
+#include <stddef.h> /* For ptrdiff_t. */
+#include <stdint.h> /* TODO: don't drag in all the macros, just the types. */
+// Include uchar.h only when needed. Bionic's stdatomic.h is also used for the
+// host (via a copy in prebuilts/clang) and uchar.h is not available in the
+// glibc used for the host.
+#if __STDC_VERSION__ >= 201112L
+# include <uchar.h> /* For char16_t and char32_t. */
+#endif
+
+
+#ifdef __clang__
+# if __has_extension(c_atomic) || __has_extension(cxx_atomic)
+# define __CLANG_ATOMICS
+# else
+# error "stdatomic.h does not support your compiler"
+# endif
+# if __has_builtin(__sync_swap)
+# define __HAS_BUILTIN_SYNC_SWAP
+# endif
+#else
+# define __GNUC_ATOMICS
+#endif
+
+/*
+ * 7.17.1 Atomic lock-free macros.
+ */
+
+#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE
+#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE
+#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE
+#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE
+#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE
+#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE
+#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_INT_LOCK_FREE
+#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_LONG_LOCK_FREE
+#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE
+#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
+#endif
+#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE
+#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
+#endif
+
+/*
+ * 7.17.2 Initialization.
+ */
+
+#if defined(__CLANG_ATOMICS)
+#define ATOMIC_VAR_INIT(value) (value)
+#define atomic_init(obj, value) __c11_atomic_init(obj, value)
+#else
+#define ATOMIC_VAR_INIT(value) { .__val = (value) }
+#define atomic_init(obj, value) ((void)((obj)->__val = (value)))
+#endif
+
+/*
+ * Clang and recent GCC both provide predefined macros for the memory
+ * orderings. If we are using a compiler that doesn't define them, use the
+ * clang values - these will be ignored in the fallback path.
+ */
+
+#ifndef __ATOMIC_RELAXED
+#define __ATOMIC_RELAXED 0
+#endif
+#ifndef __ATOMIC_CONSUME
+#define __ATOMIC_CONSUME 1
+#endif
+#ifndef __ATOMIC_ACQUIRE
+#define __ATOMIC_ACQUIRE 2
+#endif
+#ifndef __ATOMIC_RELEASE
+#define __ATOMIC_RELEASE 3
+#endif
+#ifndef __ATOMIC_ACQ_REL
+#define __ATOMIC_ACQ_REL 4
+#endif
+#ifndef __ATOMIC_SEQ_CST
+#define __ATOMIC_SEQ_CST 5
+#endif
+
+/*
+ * 7.17.3 Order and consistency.
+ *
+ * The memory_order_* constants that denote the barrier behaviour of the
+ * atomic operations.
+ * The enum values must be identical to those used by the
+ * C++ <atomic> header.
+ */
+
+typedef enum {
+ memory_order_relaxed = __ATOMIC_RELAXED,
+ memory_order_consume = __ATOMIC_CONSUME,
+ memory_order_acquire = __ATOMIC_ACQUIRE,
+ memory_order_release = __ATOMIC_RELEASE,
+ memory_order_acq_rel = __ATOMIC_ACQ_REL,
+ memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+/*
+ * 7.17.4 Fences.
+ */
+
+static __inline void
+atomic_thread_fence(memory_order __order __attribute__((unused)))
+{
+
+#ifdef __CLANG_ATOMICS
+ __c11_atomic_thread_fence(__order);
+#elif defined(__GNUC_ATOMICS)
+ __atomic_thread_fence(__order);
+#else
+ __sync_synchronize();
+#endif
+}
+
+static __inline void
+atomic_signal_fence(memory_order __order __attribute__((unused)))
+{
+
+#ifdef __CLANG_ATOMICS
+ __c11_atomic_signal_fence(__order);
+#elif defined(__GNUC_ATOMICS)
+ __atomic_signal_fence(__order);
+#else
+ __asm volatile ("" ::: "memory");
+#endif
+}
+
+/*
+ * 7.17.5 Lock-free property.
+ */
+
+#if defined(_KERNEL)
+/* Atomics in kernelspace are always lock-free. */
+#define atomic_is_lock_free(obj) \
+ ((void)(obj), (_Bool)1)
+#elif defined(__CLANG_ATOMICS)
+#define atomic_is_lock_free(obj) \
+ __c11_atomic_is_lock_free(sizeof(*(obj)))
+#elif defined(__GNUC_ATOMICS)
+#define atomic_is_lock_free(obj) \
+ __atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val)
+#else
+#define atomic_is_lock_free(obj) \
+ ((void)(obj), sizeof((obj)->__val) <= sizeof(void *))
+#endif
+
+/*
+ * 7.17.6 Atomic integer types.
+ */
+
+#ifndef __CLANG_ATOMICS
+/*
+ * No native support for _Atomic(). Place object in structure to prevent
+ * most forms of direct non-atomic access.
+ */
+#define _Atomic(T) struct { T volatile __val; }
+#endif
+
+typedef _Atomic(bool) atomic_bool;
+typedef _Atomic(char) atomic_char;
+typedef _Atomic(signed char) atomic_schar;
+typedef _Atomic(unsigned char) atomic_uchar;
+typedef _Atomic(short) atomic_short;
+typedef _Atomic(unsigned short) atomic_ushort;
+typedef _Atomic(int) atomic_int;
+typedef _Atomic(unsigned int) atomic_uint;
+typedef _Atomic(long) atomic_long;
+typedef _Atomic(unsigned long) atomic_ulong;
+typedef _Atomic(long long) atomic_llong;
+typedef _Atomic(unsigned long long) atomic_ullong;
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+ typedef _Atomic(char16_t) atomic_char16_t;
+ typedef _Atomic(char32_t) atomic_char32_t;
+#endif
+typedef _Atomic(wchar_t) atomic_wchar_t;
+typedef _Atomic(int_least8_t) atomic_int_least8_t;
+typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
+typedef _Atomic(int_least16_t) atomic_int_least16_t;
+typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
+typedef _Atomic(int_least32_t) atomic_int_least32_t;
+typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
+typedef _Atomic(int_least64_t) atomic_int_least64_t;
+typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
+typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
+typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
+typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
+typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
+typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
+typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
+typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
+typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
+typedef _Atomic(intptr_t) atomic_intptr_t;
+typedef _Atomic(uintptr_t) atomic_uintptr_t;
+typedef _Atomic(size_t) atomic_size_t;
+typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
+typedef _Atomic(intmax_t) atomic_intmax_t;
+typedef _Atomic(uintmax_t) atomic_uintmax_t;
+
+/*
+ * 7.17.7 Operations on atomic types.
+ */
+
+/*
+ * Compiler-specific operations.
+ */
+
+#if defined(__CLANG_ATOMICS)
+#define atomic_compare_exchange_strong_explicit(object, expected, \
+ desired, success, failure) \
+ __c11_atomic_compare_exchange_strong(object, expected, desired, \
+ success, failure)
+#define atomic_compare_exchange_weak_explicit(object, expected, \
+ desired, success, failure) \
+ __c11_atomic_compare_exchange_weak(object, expected, desired, \
+ success, failure)
+#define atomic_exchange_explicit(object, desired, order) \
+ __c11_atomic_exchange(object, desired, order)
+#define atomic_fetch_add_explicit(object, operand, order) \
+ __c11_atomic_fetch_add(object, operand, order)
+#define atomic_fetch_and_explicit(object, operand, order) \
+ __c11_atomic_fetch_and(object, operand, order)
+#define atomic_fetch_or_explicit(object, operand, order) \
+ __c11_atomic_fetch_or(object, operand, order)
+#define atomic_fetch_sub_explicit(object, operand, order) \
+ __c11_atomic_fetch_sub(object, operand, order)
+#define atomic_fetch_xor_explicit(object, operand, order) \
+ __c11_atomic_fetch_xor(object, operand, order)
+#define atomic_load_explicit(object, order) \
+ __c11_atomic_load(object, order)
+#define atomic_store_explicit(object, desired, order) \
+ __c11_atomic_store(object, desired, order)
+#elif defined(__GNUC_ATOMICS)
+#define atomic_compare_exchange_strong_explicit(object, expected, \
+ desired, success, failure) \
+ __atomic_compare_exchange_n(&(object)->__val, expected, \
+ desired, 0, success, failure)
+#define atomic_compare_exchange_weak_explicit(object, expected, \
+ desired, success, failure) \
+ __atomic_compare_exchange_n(&(object)->__val, expected, \
+ desired, 1, success, failure)
+#define atomic_exchange_explicit(object, desired, order) \
+ __atomic_exchange_n(&(object)->__val, desired, order)
+#define atomic_fetch_add_explicit(object, operand, order) \
+ __atomic_fetch_add(&(object)->__val, operand, order)
+#define atomic_fetch_and_explicit(object, operand, order) \
+ __atomic_fetch_and(&(object)->__val, operand, order)
+#define atomic_fetch_or_explicit(object, operand, order) \
+ __atomic_fetch_or(&(object)->__val, operand, order)
+#define atomic_fetch_sub_explicit(object, operand, order) \
+ __atomic_fetch_sub(&(object)->__val, operand, order)
+#define atomic_fetch_xor_explicit(object, operand, order) \
+ __atomic_fetch_xor(&(object)->__val, operand, order)
+#define atomic_load_explicit(object, order) \
+ __atomic_load_n(&(object)->__val, order)
+#define atomic_store_explicit(object, desired, order) \
+ __atomic_store_n(&(object)->__val, desired, order)
+#else
+#define __atomic_apply_stride(object, operand) \
+ (((__typeof__((object)->__val))0) + (operand))
+#define atomic_compare_exchange_strong_explicit(object, expected, \
+ desired, success, failure) __extension__ ({ \
+ __typeof__(expected) __ep = (expected); \
+ __typeof__(*__ep) __e = *__ep; \
+ (void)(success); (void)(failure); \
+ (bool)((*__ep = __sync_val_compare_and_swap(&(object)->__val, \
+ __e, desired)) == __e); \
+})
+#define atomic_compare_exchange_weak_explicit(object, expected, \
+ desired, success, failure) \
+ atomic_compare_exchange_strong_explicit(object, expected, \
+ desired, success, failure)
+#ifdef __HAS_BUILTIN_SYNC_SWAP
+/* Clang provides a full-barrier atomic exchange - use it if available. */
+#define atomic_exchange_explicit(object, desired, order) \
+ ((void)(order), __sync_swap(&(object)->__val, desired))
+#else
+/*
+ * __sync_lock_test_and_set() is only an acquire barrier in theory (although in
+ * practice it is usually a full barrier) so we need an explicit barrier before
+ * it.
+ */
+#define atomic_exchange_explicit(object, desired, order) \
+__extension__ ({ \
+ __typeof__(object) __o = (object); \
+ __typeof__(desired) __d = (desired); \
+ (void)(order); \
+ __sync_synchronize(); \
+ __sync_lock_test_and_set(&(__o)->__val, __d); \
+})
+#endif
+#define atomic_fetch_add_explicit(object, operand, order) \
+ ((void)(order), __sync_fetch_and_add(&(object)->__val, \
+ __atomic_apply_stride(object, operand)))
+#define atomic_fetch_and_explicit(object, operand, order) \
+ ((void)(order), __sync_fetch_and_and(&(object)->__val, operand))
+#define atomic_fetch_or_explicit(object, operand, order) \
+ ((void)(order), __sync_fetch_and_or(&(object)->__val, operand))
+#define atomic_fetch_sub_explicit(object, operand, order) \
+ ((void)(order), __sync_fetch_and_sub(&(object)->__val, \
+ __atomic_apply_stride(object, operand)))
+#define atomic_fetch_xor_explicit(object, operand, order) \
+ ((void)(order), __sync_fetch_and_xor(&(object)->__val, operand))
+#define atomic_load_explicit(object, order) \
+ ((void)(order), __sync_fetch_and_add(&(object)->__val, 0))
+#define atomic_store_explicit(object, desired, order) \
+ ((void)atomic_exchange_explicit(object, desired, order))
+#endif
+
+/*
+ * Convenience functions.
+ *
+ * Don't provide these in kernel space. In kernel space, we should be
+ * disciplined enough to always provide explicit barriers.
+ */
+
+#ifndef _KERNEL
+#define atomic_compare_exchange_strong(object, expected, desired) \
+ atomic_compare_exchange_strong_explicit(object, expected, \
+ desired, memory_order_seq_cst, memory_order_seq_cst)
+#define atomic_compare_exchange_weak(object, expected, desired) \
+ atomic_compare_exchange_weak_explicit(object, expected, \
+ desired, memory_order_seq_cst, memory_order_seq_cst)
+#define atomic_exchange(object, desired) \
+ atomic_exchange_explicit(object, desired, memory_order_seq_cst)
+#define atomic_fetch_add(object, operand) \
+ atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
+#define atomic_fetch_and(object, operand) \
+ atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
+#define atomic_fetch_or(object, operand) \
+ atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
+#define atomic_fetch_sub(object, operand) \
+ atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
+#define atomic_fetch_xor(object, operand) \
+ atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
+#define atomic_load(object) \
+ atomic_load_explicit(object, memory_order_seq_cst)
+#define atomic_store(object, desired) \
+ atomic_store_explicit(object, desired, memory_order_seq_cst)
+#endif /* !_KERNEL */
+
+/*
+ * 7.17.8 Atomic flag type and operations.
+ *
+ * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some
+ * kind of compiler built-in type we could use?
+ */
+
+typedef struct {
+ atomic_bool __flag;
+} atomic_flag;
+
+#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) }
+
+static __inline bool
+atomic_flag_test_and_set_explicit(volatile atomic_flag *__object,
+ memory_order __order)
+{
+ return (atomic_exchange_explicit(&__object->__flag, 1, __order));
+}
+
+static __inline void
+atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order)
+{
+
+ atomic_store_explicit(&__object->__flag, 0, __order);
+}
+
+#ifndef _KERNEL
+static __inline bool
+atomic_flag_test_and_set(volatile atomic_flag *__object)
+{
+
+ return (atomic_flag_test_and_set_explicit(__object,
+ memory_order_seq_cst));
+}
+
+static __inline void
+atomic_flag_clear(volatile atomic_flag *__object)
+{
+
+ atomic_flag_clear_explicit(__object, memory_order_seq_cst);
+}
+#endif /* !_KERNEL */
+
+#endif /* <atomic> unavailable */
+
+#endif /* !_STDATOMIC_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/sys/_system_properties.h
^
|
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _INCLUDE_SYS__SYSTEM_PROPERTIES_H
+#define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
+
+#include <sys/cdefs.h>
+#include <stdint.h>
+
+#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#error you should #include <sys/system_properties.h> instead
+#endif
+
+#include <sys/system_properties.h>
+
+__BEGIN_DECLS
+
+#define PROP_SERVICE_NAME "property_service"
+#define PROP_FILENAME "/dev/__properties__"
+
+#define PROP_MSG_SETPROP 1
+#define PROP_MSG_SETPROP2 0x00020001
+
+#define PROP_SUCCESS 0
+#define PROP_ERROR_READ_CMD 0x0004
+#define PROP_ERROR_READ_DATA 0x0008
+#define PROP_ERROR_READ_ONLY_PROPERTY 0x000B
+#define PROP_ERROR_INVALID_NAME 0x0010
+#define PROP_ERROR_INVALID_VALUE 0x0014
+#define PROP_ERROR_PERMISSION_DENIED 0x0018
+#define PROP_ERROR_INVALID_CMD 0x001B
+#define PROP_ERROR_HANDLE_CONTROL_MESSAGE 0x0020
+#define PROP_ERROR_SET_FAILED 0x0024
+
+/*
+** Map the property area from the specified filename. This
+** method is for testing only.
+*/
+int __system_property_set_filename(const char *filename);
+
+/*
+** Initialize the area to be used to store properties. Can
+** only be done by a single process that has write access to
+** the property area.
+*/
+int __system_property_area_init();
+
+/* Read the global serial number of the system properties
+**
+** Called to predict if a series of cached __system_property_find
+** objects will have seen __system_property_serial values change.
+** But also aids the converse, as changes in the global serial can
+** also be used to predict if a failed __system_property_find
+** could in-turn now find a new object; thus preventing the
+** cycles of effort to poll __system_property_find.
+**
+** Typically called at beginning of a cache cycle to signal if _any_ possible
+** changes have occurred since last. If there is, one may check each individual
+** __system_property_serial to confirm dirty, or __system_property_find
+** to check if the property now exists. If a call to __system_property_add
+** or __system_property_update has completed between two calls to
+** __system_property_area_serial then the second call will return a larger
+** value than the first call. Beware of race conditions as changes to the
+** properties are not atomic, the main value of this call is to determine
+** whether the expensive __system_property_find is worth retrying to see if
+** a property now exists.
+**
+** Returns the serial number on success, -1 on error.
+*/
+uint32_t __system_property_area_serial();
+
+/* Add a new system property. Can only be done by a single
+** process that has write access to the property area, and
+** that process must handle sequencing to ensure the property
+** does not already exist and that only one property is added
+** or updated at a time.
+**
+** Returns 0 on success, -1 if the property area is full.
+*/
+int __system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen);
+
+/* Update the value of a system property returned by
+** __system_property_find. Can only be done by a single process
+** that has write access to the property area, and that process
+** must handle sequencing to ensure that only one property is
+** updated at a time.
+**
+** Returns 0 on success, -1 if the parameters are incorrect.
+*/
+int __system_property_update(prop_info *pi, const char *value, unsigned int len);
+
+/* Read the serial number of a system property returned by
+** __system_property_find.
+**
+** Returns the serial number on success, -1 on error.
+*/
+uint32_t __system_property_serial(const prop_info* pi);
+
+/* Initialize the system properties area in read only mode.
+ * Should be done by all processes that need to read system
+ * properties.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int __system_properties_init();
+
+/* Deprecated: use __system_property_wait instead. */
+uint32_t __system_property_wait_any(uint32_t old_serial);
+
+__END_DECLS
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/include/sys/system_properties.h
^
|
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _INCLUDE_SYS_SYSTEM_PROPERTIES_H
+#define _INCLUDE_SYS_SYSTEM_PROPERTIES_H
+
+#include <sys/cdefs.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+typedef struct prop_info prop_info;
+
+#define PROP_VALUE_MAX 92
+
+/*
+ * Sets system property `key` to `value`, creating the system property if it doesn't already exist.
+ */
+int __system_property_set(const char* key, const char* value);
+
+/*
+ * Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
+ * Use __system_property_read_callback to query the current value.
+ *
+ * Property lookup is expensive, so it can be useful to cache the result of this function.
+ */
+const prop_info* __system_property_find(const char* name);
+
+/*
+ * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
+ */
+void __system_property_read_callback(const prop_info *pi,
+ void (*callback)(void* cookie, const char *name, const char *value, uint32_t serial),
+ void* cookie);
+
+/*
+ * Passes a `prop_info` for each system property to the provided
+ * callback. Use __system_property_read_callback() to read the value.
+ *
+ * This method is for inspecting and debugging the property system, and not generally useful.
+ */
+int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
+
+/*
+ * Waits for the specific system property identified by `pi` to be updated
+ * past `old_serial`. Waits no longer than `relative_timeout`, or forever
+ * if `relaive_timeout` is null.
+ *
+ * If `pi` is null, waits for the global serial number instead.
+ *
+ * If you don't know the current serial, use 0.
+ *
+ * Returns true and updates `*new_serial_ptr` on success, or false if the call
+ * timed out.
+ */
+struct timespec;
+bool __system_property_wait(const prop_info* pi,
+ uint32_t old_serial,
+ uint32_t* new_serial_ptr,
+ const struct timespec* relative_timeout);
+
+/* Deprecated. In Android O and above, there's no limit on property name length. */
+#define PROP_NAME_MAX 32
+/* Deprecated. Use __system_property_read_callback instead. */
+int __system_property_read(const prop_info* pi, char* name, char* value);
+/* Deprecated. Use __system_property_read_callback instead. */
+int __system_property_get(const char* name, char* value);
+/* Deprecated. Use __system_property_foreach instead. */
+const prop_info* __system_property_find_nth(unsigned n);
+
+__END_DECLS
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/CFIShadow.h
^
|
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef CFI_SHADOW_H
+#define CFI_SHADOW_H
+
+#include <stdint.h>
+
+#include "private/bionic_page.h"
+#include "private/bionic_macros.h"
+
+constexpr unsigned kLibraryAlignmentBits = 18;
+constexpr size_t kLibraryAlignment = 1UL << kLibraryAlignmentBits;
+
+// This class defines format of the shadow region for Control Flow Integrity support.
+// See documentation in http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#shared-library-support.
+//
+// CFI shadow is effectively a very fast and specialized implementation of dladdr: given an address that
+// belongs to a shared library or an executable, it can find the address of a specific export in that
+// library (a function called "__cfi_check"). This is only guaranteed to work for
+// addresses of possible CFI targets inside a library: indirectly called functions and virtual
+// tables. A random address inside a library may not work in the future (but it does in the current
+// implementation).
+//
+// Implementation is a sparse array of uint16_t where each element describes the location of
+// __cfi_check for a 2**kShadowGranularity range of memory. Array elements (called "shadow values"
+// below) are interpreted as follows.
+//
+// For an address P and corresponding shadow value V, the address of __cfi_check is calculated as
+// align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity)
+//
+// Special shadow values:
+// 0 = kInvalidShadow, this memory range has no valid CFI targets.
+// 1 = kUncheckedShadow, any address is this memory range is a valid CFI target
+//
+// Loader requirement: each aligned 2**kShadowGranularity region of address space may contain at
+// most one DSO.
+// Compiler requirement: __cfi_check is aligned at kCfiCheckGranularity.
+// Compiler requirement: __cfi_check for a given DSO is located below any CFI target for that DSO.
+class CFIShadow {
+ public:
+ static constexpr uintptr_t kShadowGranularity = kLibraryAlignmentBits;
+ static constexpr uintptr_t kCfiCheckGranularity = 12;
+
+ // Each uint16_t element of the shadow corresponds to this much application memory.
+ static constexpr uintptr_t kShadowAlign = 1UL << kShadowGranularity;
+
+ // Alignment of __cfi_check.
+ static constexpr uintptr_t kCfiCheckAlign = 1UL << kCfiCheckGranularity; // 4K
+
+#if defined (__LP64__)
+ static constexpr uintptr_t kMaxTargetAddr = 0xffffffffffff;
+#else
+ static constexpr uintptr_t kMaxTargetAddr = 0xffffffff;
+#endif
+
+ // Shadow is 2 -> 2**kShadowGranularity.
+ static constexpr uintptr_t kShadowSize =
+ align_up((kMaxTargetAddr >> (kShadowGranularity - 1)), PAGE_SIZE);
+
+ // Returns offset inside the shadow region for an address.
+ static constexpr uintptr_t MemToShadowOffset(uintptr_t x) {
+ return (x >> kShadowGranularity) << 1;
+ }
+
+ typedef int (*CFICheckFn)(uint64_t, void *, void *);
+
+ public:
+ enum ShadowValues : uint16_t {
+ kInvalidShadow = 0, // Not a valid CFI target.
+ kUncheckedShadow = 1, // Unchecked, valid CFI target.
+ kRegularShadowMin = 2 // This and all higher values encode a negative offset to __cfi_check in
+ // the units of kCfiCheckGranularity, starting with 0 at
+ // kRegularShadowMin.
+ };
+};
+
+#endif // CFI_SHADOW_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/ErrnoRestorer.h
^
|
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef ERRNO_RESTORER_H
+#define ERRNO_RESTORER_H
+
+#include <errno.h>
+
+#include "bionic_macros.h"
+
+class ErrnoRestorer {
+ public:
+ explicit ErrnoRestorer() : saved_errno_(errno) {
+ }
+
+ ~ErrnoRestorer() {
+ errno = saved_errno_;
+ }
+
+ void override(int new_errno) {
+ saved_errno_ = new_errno;
+ }
+
+ private:
+ int saved_errno_;
+
+ DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
+};
+
+#endif // ERRNO_RESTORER_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/KernelArgumentBlock.h
^
|
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef KERNEL_ARGUMENT_BLOCK_H
+#define KERNEL_ARGUMENT_BLOCK_H
+
+#include <elf.h>
+#include <link.h>
+#include <stdint.h>
+#include <sys/auxv.h>
+
+#include "private/bionic_macros.h"
+
+struct abort_msg_t;
+
+// When the kernel starts the dynamic linker, it passes a pointer to a block
+// of memory containing argc, the argv array, the environment variable array,
+// and the array of ELF aux vectors. This class breaks that block up into its
+// constituents for easy access.
+class KernelArgumentBlock {
+ public:
+ KernelArgumentBlock(void* raw_args) {
+ uintptr_t* args = reinterpret_cast<uintptr_t*>(raw_args);
+ argc = static_cast<int>(*args);
+ argv = reinterpret_cast<char**>(args + 1);
+ envp = argv + argc + 1;
+
+ // Skip over all environment variable definitions to find the aux vector.
+ // The end of the environment block is marked by a NULL pointer.
+ char** p = envp;
+ while (*p != NULL) {
+ ++p;
+ }
+ ++p; // Skip the NULL itself.
+
+ auxv = reinterpret_cast<ElfW(auxv_t)*>(p);
+ }
+
+ // Similar to ::getauxval but doesn't require the libc global variables to be set up,
+ // so it's safe to call this really early on.
+ unsigned long getauxval(unsigned long type) {
+ for (ElfW(auxv_t)* v = auxv; v->a_type != AT_NULL; ++v) {
+ if (v->a_type == type) {
+ return v->a_un.a_val;
+ }
+ }
+ return 0;
+ }
+
+ int argc;
+ char** argv;
+ char** envp;
+ ElfW(auxv_t)* auxv;
+
+ abort_msg_t** abort_message_ptr;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(KernelArgumentBlock);
+};
+
+#endif // KERNEL_ARGUMENT_BLOCK_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/NetdClientDispatch.h
^
|
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef PRIVATE_NETD_CLIENT_DISPATCH_H
+#define PRIVATE_NETD_CLIENT_DISPATCH_H
+
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+struct NetdClientDispatch {
+ int (*accept4)(int, struct sockaddr*, socklen_t*, int);
+ int (*connect)(int, const struct sockaddr*, socklen_t);
+ int (*socket)(int, int, int);
+ unsigned (*netIdForResolv)(unsigned);
+};
+
+extern __LIBC_HIDDEN__ struct NetdClientDispatch __netdClientDispatch;
+
+__END_DECLS
+
+#endif // PRIVATE_NETD_CLIENT_DISPATCH_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/ScopedPthreadMutexLocker.h
^
|
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef SCOPED_PTHREAD_MUTEX_LOCKER_H
+#define SCOPED_PTHREAD_MUTEX_LOCKER_H
+
+#include <pthread.h>
+
+#include "bionic_macros.h"
+
+class ScopedPthreadMutexLocker {
+ public:
+ explicit ScopedPthreadMutexLocker(pthread_mutex_t* mu) : mu_(mu) {
+ pthread_mutex_lock(mu_);
+ }
+
+ ~ScopedPthreadMutexLocker() {
+ pthread_mutex_unlock(mu_);
+ }
+
+ private:
+ pthread_mutex_t* mu_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
+};
+
+#endif // SCOPED_PTHREAD_MUTEX_LOCKER_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/ScopedReaddir.h
^
|
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef SCOPED_READDIR_H
+#define SCOPED_READDIR_H
+
+#include <dirent.h>
+
+#include "private/bionic_macros.h"
+
+class ScopedReaddir {
+ public:
+ ScopedReaddir(const char* path) : ScopedReaddir(opendir(path)) {
+ }
+
+ ScopedReaddir(DIR* dir) {
+ dir_ = dir;
+ }
+
+ ~ScopedReaddir() {
+ if (dir_ != NULL) {
+ closedir(dir_);
+ }
+ }
+
+ bool IsBad() {
+ return dir_ == NULL;
+ }
+
+ dirent* ReadEntry() {
+ return readdir(dir_);
+ }
+
+ private:
+ DIR* dir_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedReaddir);
+};
+
+#endif // SCOPED_READDIR_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/WriteProtected.h
^
|
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef _PRIVATE_WRITEPROTECTED_H
+#define _PRIVATE_WRITEPROTECTED_H
+
+#include <errno.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+
+#include <async_safe/log.h>
+
+#include "private/bionic_macros.h"
+#include "private/bionic_prctl.h"
+
+template <typename T>
+union WriteProtectedContents {
+ T value;
+ char padding[PAGE_SIZE];
+
+ WriteProtectedContents() = default;
+ DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
+} __attribute__((aligned(PAGE_SIZE)));
+
+// Write protected wrapper class that aligns its contents to a page boundary,
+// and sets the memory protection to be non-writable, except when being modified
+// explicitly.
+template <typename T>
+class WriteProtected {
+ static_assert(sizeof(T) < PAGE_SIZE,
+ "WriteProtected only supports contents up to PAGE_SIZE");
+ static_assert(__is_pod(T), "WriteProtected only supports POD contents");
+
+ WriteProtectedContents<T> contents;
+
+ public:
+ WriteProtected() = default;
+ DISALLOW_COPY_AND_ASSIGN(WriteProtected);
+
+ void initialize() {
+ // Not strictly necessary, but this will hopefully segfault if we initialize
+ // multiple times by accident.
+ memset(&contents, 0, sizeof(contents));
+
+ if (mprotect(&contents, PAGE_SIZE, PROT_READ)) {
+ async_safe_fatal("failed to make WriteProtected nonwritable in initialize");
+ }
+ }
+
+ const T* operator->() {
+ return &contents.value;
+ }
+
+ const T& operator*() {
+ return contents.value;
+ }
+
+ template <typename Mutator>
+ void mutate(Mutator mutator) {
+ if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
+ async_safe_fatal("failed to make WriteProtected writable in mutate: %s",
+ strerror(errno));
+ }
+ mutator(&contents.value);
+ if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) {
+ async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s",
+ strerror(errno));
+ }
+ }
+};
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/__get_tls.h
^
|
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __BIONIC_PRIVATE_GET_TLS_H_
+#define __BIONIC_PRIVATE_GET_TLS_H_
+
+#if defined(__aarch64__)
+# define __get_tls() ({ void** __val; __asm__("mrs %0, tpidr_el0" : "=r"(__val)); __val; })
+#elif defined(__arm__)
+# define __get_tls() ({ void** __val; __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); __val; })
+#elif defined(__mips__)
+# define __get_tls() \
+ /* On mips32r1, this goes via a kernel illegal instruction trap that's optimized for v1. */ \
+ ({ register void** __val asm("v1"); \
+ __asm__(".set push\n" \
+ ".set mips32r2\n" \
+ "rdhwr %0,$29\n" \
+ ".set pop\n" : "=r"(__val)); \
+ __val; })
+#elif defined(__i386__)
+# define __get_tls() ({ void** __val; __asm__("movl %%gs:0, %0" : "=r"(__val)); __val; })
+#elif defined(__x86_64__)
+# define __get_tls() ({ void** __val; __asm__("mov %%fs:0, %0" : "=r"(__val)); __val; })
+#else
+#error unsupported architecture
+#endif
+
+#endif /* __BIONIC_PRIVATE_GET_TLS_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_arc4random.h
^
|
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_ARC4RANDOM_H_
+#define _PRIVATE_BIONIC_ARC4RANDOM_H_
+
+#include <stddef.h>
+
+#include "private/KernelArgumentBlock.h"
+
+/*
+ * arc4random aborts if it's unable to fetch entropy, which is always the case
+ * for init on devices without getrandom(2), since /dev/random hasn't been
+ * created yet. Provide a wrapper function that falls back to AT_RANDOM if
+ * we don't have getrandom and /dev/urandom is missing.
+ */
+void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args);
+
+/*
+ * Return true if libc has an unlimited entropy source (something other than
+ * AT_RANDOM), and arc4random* calls will always succeed.
+ */
+bool __libc_arc4random_has_unlimited_entropy();
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_asm.h
^
|
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_ASM_H_
+#define _PRIVATE_BIONIC_ASM_H_
+
+#include <asm/unistd.h> /* For system call numbers. */
+#define MAX_ERRNO 4095 /* For recognizing system call error returns. */
+
+#define __bionic_asm_custom_entry(f)
+#define __bionic_asm_custom_end(f)
+#define __bionic_asm_function_type @function
+
+#include <machine/asm.h>
+
+#define ENTRY_NO_DWARF(f) \
+ .text; \
+ .globl f; \
+ .balign __bionic_asm_align; \
+ .type f, __bionic_asm_function_type; \
+ f: \
+ __bionic_asm_custom_entry(f); \
+
+#define ENTRY(f) \
+ ENTRY_NO_DWARF(f) \
+ .cfi_startproc \
+
+#define END_NO_DWARF(f) \
+ .size f, .-f; \
+ __bionic_asm_custom_end(f) \
+
+#define END(f) \
+ .cfi_endproc; \
+ END_NO_DWARF(f) \
+
+/* Like ENTRY, but with hidden visibility. */
+#define ENTRY_PRIVATE(f) \
+ ENTRY(f); \
+ .hidden f \
+
+/* Like ENTRY_NO_DWARF, but with hidden visibility. */
+#define ENTRY_PRIVATE_NO_DWARF(f) \
+ ENTRY_NO_DWARF(f); \
+ .hidden f \
+
+#define ALIAS_SYMBOL(alias, original) \
+ .globl alias; \
+ .equ alias, original
+
+#endif /* _PRIVATE_BIONIC_ASM_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_auxv.h
^
|
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _PRIVATE_BIONIC_AUXV_H_
+#define _PRIVATE_BIONIC_AUXV_H_
+
+#include <elf.h>
+#include <link.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+extern ElfW(auxv_t)* __libc_auxv;
+
+__END_DECLS
+
+#endif /* _PRIVATE_BIONIC_AUXV_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_config.h
^
|
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef _BIONIC_CONFIG_H_
+#define _BIONIC_CONFIG_H_
+
+// valloc(3) and pvalloc(3) were removed from POSIX 2004. We do not include them
+// for LP64, but the symbols remain in LP32 for binary compatibility.
+#if !defined(__LP64__)
+#define HAVE_DEPRECATED_MALLOC_FUNCS 1
+#endif
+
+#endif // _BIONIC_CONFIG_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_constants.h
^
|
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef _BIONIC_CONSTANTS_H_
+#define _BIONIC_CONSTANTS_H_
+
+#define NS_PER_S 1000000000
+
+#endif // _BIONIC_CONSTANTS_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_errdefs.h
^
|
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* the following corresponds to the error codes of the Linux kernel used by the Android platform
+ * these are distinct from the OpenBSD ones, which is why we need to redeclare them here
+ *
+ * this file may be included several times to define either error constants or their
+ * string representation
+ */
+
+#ifndef __BIONIC_ERRDEF
+#error "__BIONIC_ERRDEF must be defined before including this file"
+#endif
+__BIONIC_ERRDEF( 0 , 0, "Success" )
+__BIONIC_ERRDEF( EPERM , 1, "Operation not permitted" )
+__BIONIC_ERRDEF( ENOENT , 2, "No such file or directory" )
+__BIONIC_ERRDEF( ESRCH , 3, "No such process" )
+__BIONIC_ERRDEF( EINTR , 4, "Interrupted system call" )
+__BIONIC_ERRDEF( EIO , 5, "I/O error" )
+__BIONIC_ERRDEF( ENXIO , 6, "No such device or address" )
+__BIONIC_ERRDEF( E2BIG , 7, "Argument list too long" )
+__BIONIC_ERRDEF( ENOEXEC , 8, "Exec format error" )
+__BIONIC_ERRDEF( EBADF , 9, "Bad file descriptor" )
+__BIONIC_ERRDEF( ECHILD , 10, "No child processes" )
+__BIONIC_ERRDEF( EAGAIN , 11, "Try again" )
+__BIONIC_ERRDEF( ENOMEM , 12, "Out of memory" )
+__BIONIC_ERRDEF( EACCES , 13, "Permission denied" )
+__BIONIC_ERRDEF( EFAULT , 14, "Bad address" )
+__BIONIC_ERRDEF( ENOTBLK , 15, "Block device required" )
+__BIONIC_ERRDEF( EBUSY , 16, "Device or resource busy" )
+__BIONIC_ERRDEF( EEXIST , 17, "File exists" )
+__BIONIC_ERRDEF( EXDEV , 18, "Cross-device link" )
+__BIONIC_ERRDEF( ENODEV , 19, "No such device" )
+__BIONIC_ERRDEF( ENOTDIR , 20, "Not a directory" )
+__BIONIC_ERRDEF( EISDIR , 21, "Is a directory" )
+__BIONIC_ERRDEF( EINVAL , 22, "Invalid argument" )
+__BIONIC_ERRDEF( ENFILE , 23, "File table overflow" )
+__BIONIC_ERRDEF( EMFILE , 24, "Too many open files" )
+__BIONIC_ERRDEF( ENOTTY , 25, "Not a typewriter" )
+__BIONIC_ERRDEF( ETXTBSY , 26, "Text file busy" )
+__BIONIC_ERRDEF( EFBIG , 27, "File too large" )
+__BIONIC_ERRDEF( ENOSPC , 28, "No space left on device" )
+__BIONIC_ERRDEF( ESPIPE , 29, "Illegal seek" )
+__BIONIC_ERRDEF( EROFS , 30, "Read-only file system" )
+__BIONIC_ERRDEF( EMLINK , 31, "Too many links" )
+__BIONIC_ERRDEF( EPIPE , 32, "Broken pipe" )
+__BIONIC_ERRDEF( EDOM , 33, "Math argument out of domain of func" )
+__BIONIC_ERRDEF( ERANGE , 34, "Math result not representable" )
+__BIONIC_ERRDEF( EDEADLK , 35, "Resource deadlock would occur" )
+__BIONIC_ERRDEF( ENAMETOOLONG , 36, "File name too long" )
+__BIONIC_ERRDEF( ENOLCK , 37, "No record locks available" )
+__BIONIC_ERRDEF( ENOSYS , 38, "Function not implemented" )
+__BIONIC_ERRDEF( ENOTEMPTY , 39, "Directory not empty" )
+__BIONIC_ERRDEF( ELOOP , 40, "Too many symbolic links encountered" )
+__BIONIC_ERRDEF( ENOMSG , 42, "No message of desired type" )
+__BIONIC_ERRDEF( EIDRM , 43, "Identifier removed" )
+__BIONIC_ERRDEF( ECHRNG , 44, "Channel number out of range" )
+__BIONIC_ERRDEF( EL2NSYNC , 45, "Level 2 not synchronized" )
+__BIONIC_ERRDEF( EL3HLT , 46, "Level 3 halted" )
+__BIONIC_ERRDEF( EL3RST , 47, "Level 3 reset" )
+__BIONIC_ERRDEF( ELNRNG , 48, "Link number out of range" )
+__BIONIC_ERRDEF( EUNATCH , 49, "Protocol driver not attached" )
+__BIONIC_ERRDEF( ENOCSI , 50, "No CSI structure available" )
+__BIONIC_ERRDEF( EL2HLT , 51, "Level 2 halted" )
+__BIONIC_ERRDEF( EBADE , 52, "Invalid exchange" )
+__BIONIC_ERRDEF( EBADR , 53, "Invalid request descriptor" )
+__BIONIC_ERRDEF( EXFULL , 54, "Exchange full" )
+__BIONIC_ERRDEF( ENOANO , 55, "No anode" )
+__BIONIC_ERRDEF( EBADRQC , 56, "Invalid request code" )
+__BIONIC_ERRDEF( EBADSLT , 57, "Invalid slot" )
+__BIONIC_ERRDEF( EBFONT , 59, "Bad font file format" )
+__BIONIC_ERRDEF( ENOSTR , 60, "Device not a stream" )
+__BIONIC_ERRDEF( ENODATA , 61, "No data available" )
+__BIONIC_ERRDEF( ETIME , 62, "Timer expired" )
+__BIONIC_ERRDEF( ENOSR , 63, "Out of streams resources" )
+__BIONIC_ERRDEF( ENONET , 64, "Machine is not on the network" )
+__BIONIC_ERRDEF( ENOPKG , 65, "Package not installed" )
+__BIONIC_ERRDEF( EREMOTE , 66, "Object is remote" )
+__BIONIC_ERRDEF( ENOLINK , 67, "Link has been severed" )
+__BIONIC_ERRDEF( EADV , 68, "Advertise error" )
+__BIONIC_ERRDEF( ESRMNT , 69, "Srmount error" )
+__BIONIC_ERRDEF( ECOMM , 70, "Communication error on send" )
+__BIONIC_ERRDEF( EPROTO , 71, "Protocol error" )
+__BIONIC_ERRDEF( EMULTIHOP , 72, "Multihop attempted" )
+__BIONIC_ERRDEF( EDOTDOT , 73, "RFS specific error" )
+__BIONIC_ERRDEF( EBADMSG , 74, "Not a data message" )
+__BIONIC_ERRDEF( EOVERFLOW , 75, "Value too large for defined data type" )
+__BIONIC_ERRDEF( ENOTUNIQ , 76, "Name not unique on network" )
+__BIONIC_ERRDEF( EBADFD , 77, "File descriptor in bad state" )
+__BIONIC_ERRDEF( EREMCHG , 78, "Remote address changed" )
+__BIONIC_ERRDEF( ELIBACC , 79, "Can not access a needed shared library" )
+__BIONIC_ERRDEF( ELIBBAD , 80, "Accessing a corrupted shared library" )
+__BIONIC_ERRDEF( ELIBSCN , 81, ".lib section in a.out corrupted" )
+__BIONIC_ERRDEF( ELIBMAX , 82, "Attempting to link in too many shared libraries" )
+__BIONIC_ERRDEF( ELIBEXEC , 83, "Cannot exec a shared library directly" )
+__BIONIC_ERRDEF( EILSEQ , 84, "Illegal byte sequence" )
+__BIONIC_ERRDEF( ERESTART , 85, "Interrupted system call should be restarted" )
+__BIONIC_ERRDEF( ESTRPIPE , 86, "Streams pipe error" )
+__BIONIC_ERRDEF( EUSERS , 87, "Too many users" )
+__BIONIC_ERRDEF( ENOTSOCK , 88, "Socket operation on non-socket" )
+__BIONIC_ERRDEF( EDESTADDRREQ , 89, "Destination address required" )
+__BIONIC_ERRDEF( EMSGSIZE , 90, "Message too long" )
+__BIONIC_ERRDEF( EPROTOTYPE , 91, "Protocol wrong type for socket" )
+__BIONIC_ERRDEF( ENOPROTOOPT , 92, "Protocol not available" )
+__BIONIC_ERRDEF( EPROTONOSUPPORT, 93, "Protocol not supported" )
+__BIONIC_ERRDEF( ESOCKTNOSUPPORT, 94, "Socket type not supported" )
+__BIONIC_ERRDEF( EOPNOTSUPP , 95, "Operation not supported on transport endpoint" )
+__BIONIC_ERRDEF( EPFNOSUPPORT , 96, "Protocol family not supported" )
+__BIONIC_ERRDEF( EAFNOSUPPORT , 97, "Address family not supported by protocol" )
+__BIONIC_ERRDEF( EADDRINUSE , 98, "Address already in use" )
+__BIONIC_ERRDEF( EADDRNOTAVAIL , 99, "Cannot assign requested address" )
+__BIONIC_ERRDEF( ENETDOWN , 100, "Network is down" )
+__BIONIC_ERRDEF( ENETUNREACH , 101, "Network is unreachable" )
+__BIONIC_ERRDEF( ENETRESET , 102, "Network dropped connection because of reset" )
+__BIONIC_ERRDEF( ECONNABORTED , 103, "Software caused connection abort" )
+__BIONIC_ERRDEF( ECONNRESET , 104, "Connection reset by peer" )
+__BIONIC_ERRDEF( ENOBUFS , 105, "No buffer space available" )
+__BIONIC_ERRDEF( EISCONN , 106, "Transport endpoint is already connected" )
+__BIONIC_ERRDEF( ENOTCONN , 107, "Transport endpoint is not connected" )
+__BIONIC_ERRDEF( ESHUTDOWN , 108, "Cannot send after transport endpoint shutdown" )
+__BIONIC_ERRDEF( ETOOMANYREFS , 109, "Too many references: cannot splice" )
+__BIONIC_ERRDEF( ETIMEDOUT , 110, "Connection timed out" )
+__BIONIC_ERRDEF( ECONNREFUSED , 111, "Connection refused" )
+__BIONIC_ERRDEF( EHOSTDOWN , 112, "Host is down" )
+__BIONIC_ERRDEF( EHOSTUNREACH , 113, "No route to host" )
+__BIONIC_ERRDEF( EALREADY , 114, "Operation already in progress" )
+__BIONIC_ERRDEF( EINPROGRESS , 115, "Operation now in progress" )
+__BIONIC_ERRDEF( ESTALE , 116, "Stale NFS file handle" )
+__BIONIC_ERRDEF( EUCLEAN , 117, "Structure needs cleaning" )
+__BIONIC_ERRDEF( ENOTNAM , 118, "Not a XENIX named type file" )
+__BIONIC_ERRDEF( ENAVAIL , 119, "No XENIX semaphores available" )
+__BIONIC_ERRDEF( EISNAM , 120, "Is a named type file" )
+__BIONIC_ERRDEF( EREMOTEIO , 121, "Remote I/O error" )
+__BIONIC_ERRDEF( EDQUOT , 122, "Quota exceeded" )
+__BIONIC_ERRDEF( ENOMEDIUM , 123, "No medium found" )
+__BIONIC_ERRDEF( EMEDIUMTYPE , 124, "Wrong medium type" )
+__BIONIC_ERRDEF( ECANCELED , 125, "Operation Canceled" )
+__BIONIC_ERRDEF( ENOKEY , 126, "Required key not available" )
+__BIONIC_ERRDEF( EKEYEXPIRED , 127, "Key has expired" )
+__BIONIC_ERRDEF( EKEYREVOKED , 128, "Key has been revoked" )
+__BIONIC_ERRDEF( EKEYREJECTED , 129, "Key was rejected by service" )
+__BIONIC_ERRDEF( EOWNERDEAD , 130, "Owner died" )
+__BIONIC_ERRDEF( ENOTRECOVERABLE, 131, "State not recoverable" )
+
+#undef __BIONIC_ERRDEF
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_fortify.h
^
|
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <poll.h> // For struct pollfd.
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/select.h> // For struct fd_set.
+
+#include <async_safe/log.h>
+
+static inline __noreturn void __fortify_fatal(const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ async_safe_fatal_va_list("FORTIFY", fmt, args);
+ va_end(args);
+ abort();
+}
+
+//
+// Common helpers.
+//
+
+static inline void __check_fd_set(const char* fn, int fd, size_t set_size) {
+ if (__predict_false(fd < 0)) {
+ __fortify_fatal("%s: file descriptor %d < 0", fn, fd);
+ }
+ if (__predict_false(fd >= FD_SETSIZE)) {
+ __fortify_fatal("%s: file descriptor %d >= FD_SETSIZE %zu", fn, fd, set_size);
+ }
+ if (__predict_false(set_size < sizeof(fd_set))) {
+ __fortify_fatal("%s: set size %zu is too small to be an fd_set", fn, set_size);
+ }
+}
+
+static inline void __check_pollfd_array(const char* fn, size_t fds_size, nfds_t fd_count) {
+ size_t pollfd_array_length = fds_size / sizeof(pollfd);
+ if (__predict_false(pollfd_array_length < fd_count)) {
+ __fortify_fatal("%s: %zu-element pollfd array too small for %u fds",
+ fn, pollfd_array_length, fd_count);
+ }
+}
+
+static inline void __check_count(const char* fn, const char* identifier, size_t value) {
+ if (__predict_false(value > SSIZE_MAX)) {
+ __fortify_fatal("%s: %s %zu > SSIZE_MAX", fn, identifier, value);
+ }
+}
+
+static inline void __check_buffer_access(const char* fn, const char* action,
+ size_t claim, size_t actual) {
+ if (__predict_false(claim > actual)) {
+ __fortify_fatal("%s: prevented %zu-byte %s %zu-byte buffer", fn, claim, action, actual);
+ }
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_futex.h
^
|
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BIONIC_FUTEX_H
+#define _BIONIC_FUTEX_H
+
+#include <errno.h>
+#include <linux/futex.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <sys/cdefs.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+__BEGIN_DECLS
+
+struct timespec;
+
+static inline int __futex(volatile void* ftx, int op, int value,
+ const struct timespec* timeout,
+ int bitset) {
+ // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
+ int saved_errno = errno;
+ int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
+ if (result == -1) {
+ result = -errno;
+ errno = saved_errno;
+ }
+ return result;
+}
+
+static inline int __futex_wake(volatile void* ftx, int count) {
+ return __futex(ftx, FUTEX_WAKE, count, NULL, 0);
+}
+
+static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {
+ return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
+}
+
+static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+ return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
+}
+
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
+ bool use_realtime_clock, const struct timespec* abs_timeout) {
+ return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
+ (use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
+ FUTEX_BITSET_MATCH_ANY);
+}
+
+__END_DECLS
+
+#endif /* _BIONIC_FUTEX_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_globals.h
^
|
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_GLOBALS_H
+#define _PRIVATE_BIONIC_GLOBALS_H
+
+#include <sys/cdefs.h>
+
+#include "private/bionic_malloc_dispatch.h"
+#include "private/bionic_vdso.h"
+#include "private/WriteProtected.h"
+
+struct libc_globals {
+ vdso_entry vdso[VDSO_END];
+ long setjmp_cookie;
+ MallocDispatch malloc_dispatch;
+};
+
+extern WriteProtected<libc_globals> __libc_globals;
+
+class KernelArgumentBlock;
+void __libc_init_malloc(libc_globals* globals);
+void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args);
+void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args);
+
+#if defined(__i386__)
+extern void* __libc_sysinfo;
+void __libc_init_sysinfo(KernelArgumentBlock& args);
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_ieee.h
^
|
@@ -0,0 +1,118 @@
+/* $OpenBSD: ieee.h,v 1.4 2011/11/08 17:06:51 deraadt Exp $ */
+/* $NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ieee.h 8.1 (Berkeley) 6/11/93
+ */
+
+#ifndef _MACHINE_IEEE_H_
+#define _MACHINE_IEEE_H_
+
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+#define SNG_EXPBITS 8
+#define SNG_FRACBITS 23
+
+#define SNG_EXP_INFNAN 255
+#define SNG_EXP_BIAS 127
+
+struct ieee_single {
+ unsigned sng_frac:23;
+ unsigned sng_exp:8;
+ unsigned sng_sign:1;
+};
+
+#define DBL_EXPBITS 11
+#define DBL_FRACHBITS 20
+#define DBL_FRACLBITS 32
+#define DBL_FRACBITS 52
+
+#define DBL_EXP_INFNAN 2047
+#define DBL_EXP_BIAS 1023
+
+struct ieee_double {
+ unsigned dbl_fracl;
+ unsigned dbl_frach:20;
+ unsigned dbl_exp:11;
+ unsigned dbl_sign:1;
+};
+
+#if defined(__LP64__)
+
+/* 64-bit Android uses ld128 long doubles. */
+
+#define EXT_EXPBITS 15
+#define EXT_FRACHBITS 16
+#define EXT_FRACHMBITS 32
+#define EXT_FRACLMBITS 32
+#define EXT_FRACLBITS 32
+#define EXT_FRACBITS 112
+
+#define EXT_EXP_INFNAN 32767
+#define EXT_EXP_BIAS 16383
+
+#define EXT_IMPLICIT_NBIT
+
+#define EXT_TO_ARRAY32(p, a) do { \
+ (a)[0] = (uint32_t)(p)->ext_fracl; \
+ (a)[1] = (uint32_t)(p)->ext_fraclm; \
+ (a)[2] = (uint32_t)(p)->ext_frachm; \
+ (a)[3] = (uint32_t)(p)->ext_frach; \
+} while(0)
+
+struct ieee_ext {
+ unsigned ext_fracl;
+ unsigned ext_fraclm;
+ unsigned ext_frachm;
+ unsigned ext_frach:16;
+ unsigned ext_exp:15;
+ unsigned ext_sign:1;
+};
+
+#endif
+
+__END_DECLS
+
+#endif /* _MACHINE_IEEE_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_lock.h
^
|
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BIONIC_LOCK_H
+#define _BIONIC_LOCK_H
+
+#include <stdatomic.h>
+#include "private/bionic_futex.h"
+#include "private/bionic_macros.h"
+
+// Lock is used in places like pthread_rwlock_t, which can be initialized without calling
+// an initialization function. So make sure Lock can be initialized by setting its memory to 0.
+class Lock {
+ private:
+ enum LockState {
+ Unlocked = 0,
+ LockedWithoutWaiter,
+ LockedWithWaiter,
+ };
+ _Atomic(LockState) state;
+ bool process_shared;
+
+ public:
+ void init(bool process_shared) {
+ atomic_init(&state, Unlocked);
+ this->process_shared = process_shared;
+ }
+
+ bool trylock() {
+ LockState old_state = Unlocked;
+ return atomic_compare_exchange_strong_explicit(&state, &old_state,
+ LockedWithoutWaiter, memory_order_acquire, memory_order_relaxed);
+ }
+
+ void lock() {
+ LockState old_state = Unlocked;
+ if (atomic_compare_exchange_strong_explicit(&state, &old_state,
+ LockedWithoutWaiter, memory_order_acquire, memory_order_relaxed)) {
+ return;
+ }
+ while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
+ // TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
+ __futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
+ }
+ return;
+ }
+
+ void unlock() {
+ if (atomic_exchange_explicit(&state, Unlocked, memory_order_release) == LockedWithWaiter) {
+ __futex_wake_ex(&state, process_shared, 1);
+ }
+ }
+};
+
+#endif // _BIONIC_LOCK_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_macros.h
^
|
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _BIONIC_MACROS_H_
+#define _BIONIC_MACROS_H_
+
+#include <stdint.h>
+
+// Frameworks OpenGL code currently leaks this header and allows
+// collisions with other declarations, e.g., from libnativehelper.
+// TODO: Remove once cleaned up. b/18334516
+#if !defined(DISALLOW_COPY_AND_ASSIGN)
+// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions.
+// It goes in the private: declarations in a class.
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete
+#endif // !defined(DISALLOW_COPY_AND_ASSIGN)
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName() = delete; \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+#define BIONIC_ALIGN(value, alignment) \
+ (((value) + (alignment) - 1) & ~((alignment) - 1))
+
+#define BIONIC_ROUND_UP_POWER_OF_2(value) \
+ ((sizeof(value) == 8) \
+ ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
+ : (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value)))))
+
+static constexpr uintptr_t align_down(uintptr_t p, size_t align) {
+ return p & ~(align - 1);
+}
+
+static constexpr uintptr_t align_up(uintptr_t p, size_t align) {
+ return (p + align - 1) & ~(align - 1);
+}
+
+template <typename T>
+static inline T* align_down(T* p, size_t align) {
+ return reinterpret_cast<T*>(align_down(reinterpret_cast<uintptr_t>(p), align));
+}
+
+template <typename T>
+static inline T* align_up(T* p, size_t align) {
+ return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
+}
+
+#endif // _BIONIC_MACROS_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_malloc_dispatch.h
^
|
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_MALLOC_DISPATCH_H
+#define _PRIVATE_BIONIC_MALLOC_DISPATCH_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <private/bionic_config.h>
+
+// Entry in malloc dispatch table.
+typedef void* (*MallocCalloc)(size_t, size_t);
+typedef void (*MallocFree)(void*);
+typedef struct mallinfo (*MallocMallinfo)();
+typedef void* (*MallocMalloc)(size_t);
+typedef size_t (*MallocMallocUsableSize)(const void*);
+typedef void* (*MallocMemalign)(size_t, size_t);
+typedef int (*MallocPosixMemalign)(void**, size_t, size_t);
+typedef void* (*MallocRealloc)(void*, size_t);
+typedef int (*MallocIterate)(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+typedef void (*MallocMallocDisable)();
+typedef void (*MallocMallocEnable)();
+typedef int (*MallocMallopt)(int, int);
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+typedef void* (*MallocPvalloc)(size_t);
+typedef void* (*MallocValloc)(size_t);
+#endif
+
+struct MallocDispatch {
+ MallocCalloc calloc;
+ MallocFree free;
+ MallocMallinfo mallinfo;
+ MallocMalloc malloc;
+ MallocMallocUsableSize malloc_usable_size;
+ MallocMemalign memalign;
+ MallocPosixMemalign posix_memalign;
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ MallocPvalloc pvalloc;
+#endif
+ MallocRealloc realloc;
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ MallocValloc valloc;
+#endif
+ MallocIterate iterate;
+ MallocMallocDisable malloc_disable;
+ MallocMallocEnable malloc_enable;
+ MallocMallopt mallopt;
+} __attribute__((aligned(32)));
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_mbstate.h
^
|
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BIONIC_MBSTATE_H
+#define _BIONIC_MBSTATE_H
+
+#include <wchar.h>
+
+__BEGIN_DECLS
+
+/*
+ * These return values are specified by POSIX for multibyte conversion
+ * functions.
+ */
+#define __MB_ERR_ILLEGAL_SEQUENCE static_cast<size_t>(-1)
+#define __MB_ERR_INCOMPLETE_SEQUENCE static_cast<size_t>(-2)
+
+#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
+ rv == __MB_ERR_INCOMPLETE_SEQUENCE)
+
+static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
+ return
+ (ps->__seq[2] != 0) ? 3 :
+ (ps->__seq[1] != 0) ? 2 :
+ (ps->__seq[0] != 0) ? 1 : 0;
+}
+
+static inline void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
+ ps->__seq[i] = static_cast<uint8_t>(byte);
+}
+
+static inline __wur uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
+ return ps->__seq[n];
+}
+
+static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
+ errno = _errno;
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return __MB_ERR_ILLEGAL_SEQUENCE;
+}
+
+static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return _return;
+}
+
+__END_DECLS
+
+#endif // _BIONIC_MBSTATE_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_page.h
^
|
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef _BIONIC_PAGE_H_
+#define _BIONIC_PAGE_H_
+
+// Get PAGE_SIZE and PAGE_MASK.
+#include <sys/user.h>
+
+// Returns the address of the page containing address 'x'.
+#define PAGE_START(x) ((x) & PAGE_MASK)
+
+// Returns the offset of address 'x' in its page.
+#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
+
+// Returns the address of the next page after address 'x', unless 'x' is
+// itself at the start of a page.
+#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
+
+#endif // _BIONIC_PAGE_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_prctl.h
^
|
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef BIONIC_PRCTL_H
+#define BIONIC_PRCTL_H
+
+#include <sys/prctl.h>
+
+// This is only supported by Android kernels, so it's not in the uapi headers.
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
+
+#endif // BIONIC_PRCTL_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_sdk_version.h
^
|
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _BIONIC_SDK_VERSION_H_
+#define _BIONIC_SDK_VERSION_H_
+
+#include <stdint.h>
+
+uint32_t bionic_get_application_target_sdk_version();
+
+#endif // _BIONIC_SDK_VERSION_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_sigdefs.h
^
|
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * this header is used to define signal constants and names;
+ * it might be included several times
+ */
+
+#ifndef __BIONIC_SIGDEF
+#error __BIONIC_SIGDEF not defined
+#endif
+
+__BIONIC_SIGDEF(SIGHUP, "Hangup")
+__BIONIC_SIGDEF(SIGINT, "Interrupt")
+__BIONIC_SIGDEF(SIGQUIT, "Quit")
+__BIONIC_SIGDEF(SIGILL, "Illegal instruction")
+__BIONIC_SIGDEF(SIGTRAP, "Trap")
+__BIONIC_SIGDEF(SIGABRT, "Aborted")
+#ifdef SIGEMT
+__BIONIC_SIGDEF(SIGEMT, "EMT")
+#endif
+__BIONIC_SIGDEF(SIGFPE, "Floating point exception")
+__BIONIC_SIGDEF(SIGKILL, "Killed")
+__BIONIC_SIGDEF(SIGBUS, "Bus error")
+__BIONIC_SIGDEF(SIGSEGV, "Segmentation fault")
+__BIONIC_SIGDEF(SIGPIPE, "Broken pipe")
+__BIONIC_SIGDEF(SIGALRM, "Alarm clock")
+__BIONIC_SIGDEF(SIGTERM, "Terminated")
+__BIONIC_SIGDEF(SIGUSR1, "User signal 1")
+__BIONIC_SIGDEF(SIGUSR2, "User signal 2")
+__BIONIC_SIGDEF(SIGCHLD, "Child exited")
+__BIONIC_SIGDEF(SIGPWR, "Power failure")
+__BIONIC_SIGDEF(SIGWINCH, "Window size changed")
+__BIONIC_SIGDEF(SIGURG, "Urgent I/O condition")
+__BIONIC_SIGDEF(SIGIO, "I/O possible")
+__BIONIC_SIGDEF(SIGSTOP, "Stopped (signal)")
+__BIONIC_SIGDEF(SIGTSTP, "Stopped")
+__BIONIC_SIGDEF(SIGCONT, "Continue")
+__BIONIC_SIGDEF(SIGTTIN, "Stopped (tty input)")
+__BIONIC_SIGDEF(SIGTTOU, "Stopped (tty output)")
+__BIONIC_SIGDEF(SIGVTALRM, "Virtual timer expired")
+__BIONIC_SIGDEF(SIGPROF, "Profiling timer expired")
+__BIONIC_SIGDEF(SIGXCPU, "CPU time limit exceeded")
+__BIONIC_SIGDEF(SIGXFSZ, "File size limit exceeded")
+#if defined(SIGSTKFLT)
+__BIONIC_SIGDEF(SIGSTKFLT, "Stack fault")
+#endif
+__BIONIC_SIGDEF(SIGSYS, "Bad system call")
+
+#undef __BIONIC_SIGDEF
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_ssp.h
^
|
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_SSP_H
+#define _PRIVATE_SSP_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* GCC uses this on ARM and MIPS; we use it on x86 to set the guard in TLS. */
+extern uintptr_t __stack_chk_guard;
+
+/* GCC calls this if a stack guard check fails. */
+extern void __stack_chk_fail();
+
+__END_DECLS
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_string_utils.h
^
|
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef _BIONIC_STRING_UTILS_H_
+#define _BIONIC_STRING_UTILS_H_
+
+#include <string.h>
+
+static inline bool ends_with(const char* s1, const char* s2) {
+ size_t s1_length = strlen(s1);
+ size_t s2_length = strlen(s2);
+ if (s2_length > s1_length) {
+ return false;
+ }
+ return memcmp(s1 + (s1_length - s2_length), s2, s2_length) == 0;
+}
+
+#endif // _BIONIC_STRING_UTILS_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_systrace.h
^
|
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef BIONIC_SYSTRACE_H
+#define BIONIC_SYSTRACE_H
+
+#include "bionic_macros.h"
+
+// Tracing class for bionic. To begin a trace at a specified point:
+// ScopedTrace("Trace message");
+// The trace will end when the contructor goes out of scope.
+
+// stubbed for hybris support
+class ScopedTrace {
+ public:
+ explicit ScopedTrace(const char* message) {};
+ ~ScopedTrace() {};
+
+ void End() {};
+ private:
+ bool called_end_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
+};
+
+// stubbed for hybris support:
+static inline void bionic_trace_begin(const char* message) {};
+static inline void bionic_trace_end() {};
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_time_conversions.h
^
|
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BIONIC_TIME_CONVERSIONS_H
+#define _BIONIC_TIME_CONVERSIONS_H
+
+#include <errno.h>
+#include <time.h>
+#include <sys/cdefs.h>
+
+#include "private/bionic_constants.h"
+
+__BEGIN_DECLS
+
+__LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv);
+__LIBC_HIDDEN__ void timespec_from_ms(timespec& ts, const int ms);
+
+__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
+
+__END_DECLS
+
+static inline int check_timespec(const timespec* ts, bool null_allowed) {
+ if (null_allowed && ts == nullptr) {
+ return 0;
+ }
+ // glibc just segfaults if you pass a null timespec.
+ // That seems a lot more likely to catch bad code than returning EINVAL.
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= NS_PER_S) {
+ return EINVAL;
+ }
+ if (ts->tv_sec < 0) {
+ return ETIMEDOUT;
+ }
+ return 0;
+}
+
+#if !defined(__LP64__)
+static inline void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts, clockid_t clock) {
+ clock_gettime(clock, &abs_ts);
+ abs_ts.tv_sec += ts.tv_sec;
+ abs_ts.tv_nsec += ts.tv_nsec;
+ if (abs_ts.tv_nsec >= NS_PER_S) {
+ abs_ts.tv_nsec -= NS_PER_S;
+ abs_ts.tv_sec++;
+ }
+}
+#endif
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_tls.h
^
|
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __BIONIC_PRIVATE_BIONIC_TLS_H_
+#define __BIONIC_PRIVATE_BIONIC_TLS_H_
+
+#include <locale.h>
+#include <mntent.h>
+#include <stdio.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include "bionic_macros.h"
+#include "__get_tls.h"
+#include "grp_pwd.h"
+
+__BEGIN_DECLS
+
+/** WARNING WARNING WARNING
+ **
+ ** This header file is *NOT* part of the public Bionic ABI/API
+ ** and should not be used/included by user-serviceable parts of
+ ** the system (e.g. applications).
+ **
+ ** It is only provided here for the benefit of the system dynamic
+ ** linker and the OpenGL sub-system (which needs to access the
+ ** pre-allocated slot directly for performance reason).
+ **/
+
+// Well-known TLS slots. What data goes in which slot is arbitrary unless otherwise noted.
+enum {
+ TLS_SLOT_SELF = 0, // The kernel requires this specific slot for x86.
+ TLS_SLOT_THREAD_ID,
+ TLS_SLOT_ERRNO,
+
+ // These two aren't used by bionic itself, but allow the graphics code to
+ // access TLS directly rather than using the pthread API.
+ TLS_SLOT_OPENGL_API = 3,
+ TLS_SLOT_OPENGL = 4,
+
+ // This slot is only used to pass information from the dynamic linker to
+ // libc.so when the C library is loaded in to memory. The C runtime init
+ // function will then clear it. Since its use is extremely temporary,
+ // we reuse an existing location that isn't needed during libc startup.
+ TLS_SLOT_BIONIC_PREINIT = TLS_SLOT_OPENGL_API,
+
+ TLS_SLOT_STACK_GUARD = 5, // GCC requires this specific slot for x86.
+ TLS_SLOT_DLERROR,
+
+ // Fast storage for Thread::Current() in ART.
+ TLS_SLOT_ART_THREAD_SELF,
+
+ // Lets TSAN avoid using pthread_getspecific for finding the current thread
+ // state.
+ TLS_SLOT_TSAN,
+
+ BIONIC_TLS_SLOTS // Must come last!
+};
+
+// ~3 pages.
+struct bionic_tls {
+ locale_t locale;
+
+ char basename_buf[MAXPATHLEN];
+ char dirname_buf[MAXPATHLEN];
+
+ mntent mntent_buf;
+ char mntent_strings[BUFSIZ];
+
+ char ptsname_buf[32];
+ char ttyname_buf[64];
+
+ char strerror_buf[NL_TEXTMAX];
+ char strsignal_buf[NL_TEXTMAX];
+
+ group_state_t group;
+ passwd_state_t passwd;
+};
+
+#define BIONIC_TLS_SIZE (BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
+
+/*
+ * Bionic uses some pthread keys internally. All pthread keys used internally
+ * should be created in constructors, except for keys that may be used in or
+ * before constructors.
+ *
+ * We need to manually maintain the count of pthread keys used internally, but
+ * pthread_test should fail if we forget.
+ *
+ * These are the pthread keys currently used internally by libc:
+ * _res_key libc (constructor in BSD code)
+ */
+
+#define LIBC_PTHREAD_KEY_RESERVED_COUNT 1
+
+/* Internally, jemalloc uses a single key for per thread data. */
+#define JEMALLOC_PTHREAD_KEY_RESERVED_COUNT 1
+#define BIONIC_PTHREAD_KEY_RESERVED_COUNT (LIBC_PTHREAD_KEY_RESERVED_COUNT + JEMALLOC_PTHREAD_KEY_RESERVED_COUNT)
+
+/*
+ * Maximum number of pthread keys allocated.
+ * This includes pthread keys used internally and externally.
+ */
+#define BIONIC_PTHREAD_KEY_COUNT (BIONIC_PTHREAD_KEY_RESERVED_COUNT + PTHREAD_KEYS_MAX)
+
+__END_DECLS
+
+#if defined(__cplusplus)
+class KernelArgumentBlock;
+extern void __libc_init_main_thread(KernelArgumentBlock&);
+#endif
+
+#endif /* __BIONIC_PRIVATE_BIONIC_TLS_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/bionic_vdso.h
^
|
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_VDSO_H
+#define _PRIVATE_BIONIC_VDSO_H
+
+#include <time.h>
+
+#if defined(__aarch64__)
+#define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__kernel_gettimeofday"
+#else
+#define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__vdso_gettimeofday"
+#endif
+
+extern "C" int __clock_gettime(int, timespec*);
+extern "C" int __gettimeofday(timeval*, struct timezone*);
+
+struct vdso_entry {
+ const char* name;
+ void* fn;
+};
+
+enum {
+ VDSO_CLOCK_GETTIME = 0,
+ VDSO_GETTIMEOFDAY,
+ VDSO_END
+};
+
+#endif // _PRIVATE_BIONIC_VDSO_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/get_cpu_count_from_string.h
^
|
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+
+// Parse a string like: 0, 2-4, 6.
+static int GetCpuCountFromString(const char* s) {
+ int cpu_count = 0;
+ int last_cpu = -1;
+ while (*s != '\0') {
+ if (isdigit(*s)) {
+ int cpu = static_cast<int>(strtol(s, const_cast<char**>(&s), 10));
+ if (last_cpu != -1) {
+ cpu_count += cpu - last_cpu;
+ } else {
+ cpu_count++;
+ }
+ last_cpu = cpu;
+ } else {
+ if (*s == ',') {
+ last_cpu = -1;
+ }
+ s++;
+ }
+ }
+ return cpu_count;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/grp_pwd.h
^
|
@@ -0,0 +1,48 @@
+#pragma once
+
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <grp.h>
+#include <pwd.h>
+
+struct group_state_t {
+ group group_;
+ char* group_members_[2];
+ char group_name_buffer_[32];
+ // Must be last so init_group_state can run a simple memset for the above
+ ssize_t getgrent_idx;
+};
+
+struct passwd_state_t {
+ passwd passwd_;
+ char name_buffer_[32];
+ char dir_buffer_[32];
+ char sh_buffer_[32];
+ ssize_t getpwent_idx;
+};
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/icu.h
^
|
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_ICU_H
+#define _PRIVATE_ICU_H
+
+#include <stdint.h>
+
+typedef int8_t UBool;
+typedef int32_t UChar32;
+
+enum UProperty {
+ UCHAR_ALPHABETIC = 0,
+ UCHAR_LOWERCASE = 22,
+ UCHAR_POSIX_ALNUM = 44,
+ UCHAR_POSIX_BLANK = 45,
+ UCHAR_POSIX_GRAPH = 46,
+ UCHAR_POSIX_PRINT = 47,
+ UCHAR_POSIX_XDIGIT = 48,
+ UCHAR_UPPERCASE = 30,
+ UCHAR_WHITE_SPACE = 31,
+};
+
+enum UCharCategory {
+ U_CONTROL_CHAR = 15,
+};
+
+void* __find_icu_symbol(const char* symbol_name);
+
+#endif // _PRIVATE_ICU_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/kernel_sigset_t.h
^
|
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef LIBC_PRIVATE_KERNEL_SIGSET_T_H_
+#define LIBC_PRIVATE_KERNEL_SIGSET_T_H_
+
+#include <signal.h>
+
+// Our sigset_t is wrong for ARM and x86. It's 32-bit but the kernel expects 64 bits.
+// This means we can't support real-time signals correctly until we can change the ABI.
+// In the meantime, we can use this union to pass an appropriately-sized block of memory
+// to the kernel, at the cost of not being able to refer to real-time signals.
+union kernel_sigset_t {
+ kernel_sigset_t() {
+ clear();
+ }
+
+ kernel_sigset_t(const sigset_t* value) {
+ clear();
+ set(value);
+ }
+
+ void clear() {
+ __builtin_memset(this, 0, sizeof(*this));
+ }
+
+ void set(const sigset_t* value) {
+ bionic = *value;
+ }
+
+ sigset_t* get() {
+ return &bionic;
+ }
+
+ sigset_t bionic;
+#ifndef __mips__
+ uint32_t kernel[2];
+#endif
+};
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/bionic/libc/private/thread_private.h
^
|
@@ -0,0 +1,57 @@
+/* $OpenBSD: thread_private.h,v 1.18 2006/02/22 07:16:31 otto Exp $ */
+
+/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
+
+#ifndef _THREAD_PRIVATE_H_
+#define _THREAD_PRIVATE_H_
+
+#include <pthread.h>
+
+__BEGIN_DECLS
+
+/*
+ * This file defines the thread library interface to libc. Thread
+ * libraries must implement the functions described here for proper
+ * inter-operation with libc. libc contains weak versions of the
+ * described functions for operation in a non-threaded environment.
+ */
+
+/*
+ * helper macro to make unique names in the thread namespace
+ */
+#define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name)
+
+struct __thread_private_tag_t {
+ pthread_mutex_t _private_lock;
+ pthread_key_t _private_key;
+};
+
+#define _THREAD_PRIVATE_MUTEX(name) \
+ static struct __thread_private_tag_t __THREAD_NAME(name) = { PTHREAD_MUTEX_INITIALIZER, -1 }
+#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
+ pthread_mutex_lock( &__THREAD_NAME(name)._private_lock )
+#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
+ pthread_mutex_unlock( &__THREAD_NAME(name)._private_lock )
+
+/* Note that these aren't compatible with the usual OpenBSD ones which lazy-initialize! */
+#define _MUTEX_LOCK(l) pthread_mutex_lock((pthread_mutex_t*) l)
+#define _MUTEX_UNLOCK(l) pthread_mutex_unlock((pthread_mutex_t*) l)
+
+__LIBC_HIDDEN__ void _thread_atexit_lock(void);
+__LIBC_HIDDEN__ void _thread_atexit_unlock(void);
+
+#define _ATEXIT_LOCK() _thread_atexit_lock()
+#define _ATEXIT_UNLOCK() _thread_atexit_unlock()
+
+__LIBC_HIDDEN__ void _thread_arc4_lock(void);
+__LIBC_HIDDEN__ void _thread_arc4_unlock(void);
+
+#define _ARC4_LOCK() _thread_arc4_lock()
+#define _ARC4_UNLOCK() _thread_arc4_unlock()
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+extern volatile sig_atomic_t _rs_forked;
+
+__END_DECLS
+
+#endif /* _THREAD_PRIVATE_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/dlfcn.cpp
^
|
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hybris_compat.h"
+
+#include "linker.h"
+#include "linker_cfi.h"
+#include "linker_globals.h"
+#include "linker_dlwarning.h"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <android/api-level.h>
+
+#include <bionic/pthread_internal.h>
+#include "private/bionic_tls.h"
+#include "private/ScopedPthreadMutexLocker.h"
+
+static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+static __thread char *dl_err_str;
+char __thread dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
+
+static char* __bionic_set_dlerror(char* new_value) {
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+ char** dlerror_slot = &reinterpret_cast<char**>(__get_tls())[TLS_SLOT_DLERROR];
+
+ char* old_value = *dlerror_slot;
+ *dlerror_slot = new_value;
+ if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value);
+ return old_value;
+#else
+ char *old_value = dl_err_str;
+ dl_err_str = new_value;
+ return old_value;
+#endif
+}
+
+static void __bionic_format_dlerror(const char* msg, const char* detail) {
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+ char* buffer = __get_thread()->dlerror_buffer;
+#else
+ char* buffer = dlerror_buffer;
+#endif
+ strlcpy(buffer, msg, __BIONIC_DLERROR_BUFFER_SIZE);
+ if (detail != nullptr) {
+ strlcat(buffer, ": ", __BIONIC_DLERROR_BUFFER_SIZE);
+ strlcat(buffer, detail, __BIONIC_DLERROR_BUFFER_SIZE);
+ }
+
+ __bionic_set_dlerror(buffer);
+}
+
+char* __dlerror() {
+ char* old_value = __bionic_set_dlerror(nullptr);
+ return old_value;
+}
+
+void __android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ do_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void __android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ do_android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+static void* dlopen_ext(const char* filename,
+ int flags,
+ const android_dlextinfo* extinfo,
+ const void* caller_addr) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ g_linker_logger.ResetState();
+ void* result = do_dlopen(filename, flags, extinfo, caller_addr);
+ if (result == nullptr) {
+ __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
+ return nullptr;
+ }
+ return result;
+}
+
+void* __android_dlopen_ext(const char* filename,
+ int flags,
+ const android_dlextinfo* extinfo,
+ const void* caller_addr) {
+ return dlopen_ext(filename, flags, extinfo, caller_addr);
+}
+
+void* __dlopen(const char* filename, int flags, const void* caller_addr) {
+ return dlopen_ext(filename, flags, nullptr, caller_addr);
+}
+
+void* dlsym_impl(void* handle, const char* symbol, const char* version, const void* caller_addr) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ g_linker_logger.ResetState();
+ void* result;
+ if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
+ __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
+ return nullptr;
+ }
+
+ return result;
+}
+
+void* __dlsym(void* handle, const char* symbol, const void* caller_addr) {
+ return dlsym_impl(handle, symbol, nullptr, caller_addr);
+}
+
+void* __dlvsym(void* handle, const char* symbol, const char* version, const void* caller_addr) {
+ return dlsym_impl(handle, symbol, version, caller_addr);
+}
+
+int __dladdr(const void* addr, Dl_info* info) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ return do_dladdr(addr, info);
+}
+
+int __dlclose(void* handle) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ int result = do_dlclose(handle);
+ if (result != 0) {
+ __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
+ }
+ return result;
+}
+
+// This function is needed by libgcc.a (this is why there is no prefix for this one) // in hybris there is a prefix, libgcc.a from android doesn't affect us here.
+int __android_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ return do_dl_iterate_phdr(cb, data);
+}
+
+#if defined(__arm__)
+_Unwind_Ptr __android_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ return do_dl_unwind_find_exidx(pc, pcount);
+}
+#endif
+
+void __android_set_application_target_sdk_version(uint32_t target) {
+ // lock to avoid modification in the middle of dlopen.
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ set_application_target_sdk_version(target);
+}
+
+uint32_t __android_get_application_target_sdk_version() {
+ return get_application_target_sdk_version();
+}
+
+void __android_dlwarning(void* obj, void (*f)(void*, const char*)) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ get_dlwarning(obj, f);
+}
+
+bool __android_init_anonymous_namespace(const char* shared_libs_sonames,
+ const char* library_search_path) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ bool success = init_anonymous_namespace(shared_libs_sonames, library_search_path);
+ if (!success) {
+ __bionic_format_dlerror("android_init_anonymous_namespace failed", linker_get_error_buffer());
+ }
+
+ return success;
+}
+
+android_namespace_t* __android_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ android_namespace_t* parent_namespace,
+ const void* caller_addr) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+
+ android_namespace_t* result = create_namespace(caller_addr,
+ name,
+ ld_library_path,
+ default_library_path,
+ type,
+ permitted_when_isolated_path,
+ parent_namespace);
+
+ if (result == nullptr) {
+ __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
+ }
+
+ return result;
+}
+
+bool __android_link_namespaces(android_namespace_t* namespace_from,
+ android_namespace_t* namespace_to,
+ const char* shared_libs_sonames) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+
+ bool success = link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
+
+ if (!success) {
+ __bionic_format_dlerror("android_link_namespaces failed", linker_get_error_buffer());
+ }
+
+ return success;
+}
+
+android_namespace_t* __android_get_exported_namespace(const char* name) {
+ return get_exported_namespace(name);
+}
+
+void __cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *CallerPc) {
+ CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc);
+}
+
+// name_offset: starting index of the name in libdl_info.strtab
+#define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \
+ { name_offset, \
+ reinterpret_cast<Elf32_Addr>(value), \
+ /* st_size */ 0, \
+ ((shndx) == 0) ? 0 : (STB_GLOBAL << 4), \
+ /* st_other */ 0, \
+ shndx, \
+ }
+
+#define ELF64_SYM_INITIALIZER(name_offset, value, shndx) \
+ { name_offset, \
+ ((shndx) == 0) ? 0 : (STB_GLOBAL << 4), \
+ /* st_other */ 0, \
+ shndx, \
+ reinterpret_cast<Elf64_Addr>(value), \
+ /* st_size */ 0, \
+ }
+
+#if defined(__arm__)
+_Unwind_Ptr __android_dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount);
+#endif
+
+static const char ANDROID_LIBDL_STRTAB[] =
+ // 0000000000111111 11112222222222333 333333344444444 44555555555566666 6666677777777778 8888888889999999999
+ // 0123456789012345 67890123456789012 345678901234567 89012345678901234 5678901234567890 1234567890123456789
+ "__loader_dlopen\0__loader_dlclose\0__loader_dlsym\0__loader_dlerror\0__loader_dladdr\0__loader_android_up"
+ // 1*
+ // 000000000011111111112 2222222223333333333444444444455555555 5566666666667777777777888 88888889999999999
+ // 012345678901234567890 1234567890123456789012345678901234567 8901234567890123456789012 34567890123456789
+ "date_LD_LIBRARY_PATH\0__loader_android_get_LD_LIBRARY_PATH\0__loader_dl_iterate_phdr\0__loader_android_"
+ // 2*
+ // 00000000001 1111111112222222222333333333344444444445555555555666 6666666777777777788888888889999999999
+ // 01234567890 1234567890123456789012345678901234567890123456789012 3456789012345678901234567890123456789
+ "dlopen_ext\0__loader_android_set_application_target_sdk_version\0__loader_android_get_application_targ"
+ // 3*
+ // 000000000011111 111112222222222333333333344444444445555555 5556666666666777777777788888888889 999999999
+ // 012345678901234 567890123456789012345678901234567890123456 7890123456789012345678901234567890 123456789
+ "et_sdk_version\0__loader_android_init_anonymous_namespace\0__loader_android_create_namespace\0__loader_"
+ // 4*
+ // 0000000 000111111111122222222223333 333333444444444455 555555556666666666777777777788888 888889999999999
+ // 0123456 789012345678901234567890123 456789012345678901 234567890123456789012345678901234 567890123456789
+ "dlvsym\0__loader_android_dlwarning\0__loader_cfi_fail\0__loader_android_link_namespaces\0__loader_androi"
+ // 5*
+ // 0000000000111111111122222 22222
+ // 0123456789012345678901234 56789
+ "d_get_exported_namespace\0"
+#if defined(__arm__)
+ // 525
+ "__loader_dl_unwind_find_exidx\0"
+#endif
+ ;
+
+static ElfW(Sym) g_libdl_symtab[] = {
+ // Total length of libdl_info.strtab, including trailing 0.
+ // This is actually the STH_UNDEF entry. Technically, it's
+ // supposed to have st_name == 0, but instead, it points to an index
+ // in the strtab with a \0 to make iterating through the symtab easier.
+ ELFW(SYM_INITIALIZER)(sizeof(ANDROID_LIBDL_STRTAB) - 1, nullptr, 0),
+ ELFW(SYM_INITIALIZER)( 0, &__dlopen, 1),
+ ELFW(SYM_INITIALIZER)( 16, &__dlclose, 1),
+ ELFW(SYM_INITIALIZER)( 33, &__dlsym, 1),
+ ELFW(SYM_INITIALIZER)( 48, &__dlerror, 1),
+ ELFW(SYM_INITIALIZER)( 65, &__dladdr, 1),
+ ELFW(SYM_INITIALIZER)( 81, &__android_update_LD_LIBRARY_PATH, 1),
+ ELFW(SYM_INITIALIZER)(121, &__android_get_LD_LIBRARY_PATH, 1),
+ ELFW(SYM_INITIALIZER)(158, &__android_dl_iterate_phdr, 1),
+ ELFW(SYM_INITIALIZER)(183, &__android_dlopen_ext, 1),
+ ELFW(SYM_INITIALIZER)(211, &__android_set_application_target_sdk_version, 1),
+ ELFW(SYM_INITIALIZER)(263, &__android_get_application_target_sdk_version, 1),
+ ELFW(SYM_INITIALIZER)(315, &__android_init_anonymous_namespace, 1),
+ ELFW(SYM_INITIALIZER)(357, &__android_create_namespace, 1),
+ ELFW(SYM_INITIALIZER)(391, &__dlvsym, 1),
+ ELFW(SYM_INITIALIZER)(407, &__android_dlwarning, 1),
+ ELFW(SYM_INITIALIZER)(434, &__cfi_fail, 1),
+ ELFW(SYM_INITIALIZER)(452, &__android_link_namespaces, 1),
+ ELFW(SYM_INITIALIZER)(485, &__android_get_exported_namespace, 1),
+#if defined(__arm__)
+ ELFW(SYM_INITIALIZER)(525, &__android_dl_unwind_find_exidx, 1),
+#endif
+};
+
+// Fake out a hash table with a single bucket.
+//
+// A search of the hash table will look through g_libdl_symtab starting with index 1, then
+// use g_libdl_chains to find the next index to look at. g_libdl_chains should be set up to
+// walk through every element in g_libdl_symtab, and then end with 0 (sentinel value).
+//
+// That is, g_libdl_chains should look like { 0, 2, 3, ... N, 0 } where N is the number
+// of actual symbols, or nelems(g_libdl_symtab)-1 (since the first element of g_libdl_symtab is not
+// a real symbol). (See soinfo_elf_lookup().)
+//
+// Note that adding any new symbols here requires stubbing them out in libdl.
+static unsigned g_libdl_buckets[1] = { 1 };
+#if defined(__arm__)
+static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0 };
+#else
+static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0 };
+#endif
+
+static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
+static soinfo* __libdl_info = nullptr;
+
+// This is used by the dynamic linker. Every process gets these symbols for free.
+soinfo* get_libdl_info(const char* linker_path, const link_map& linker_map) {
+ if (__libdl_info == nullptr) {
+ __libdl_info = new (__libdl_info_buf) soinfo(g_default_namespace, linker_path, nullptr, 0, 0);
+ __libdl_info->flags_ |= FLAG_LINKED;
+ __libdl_info->strtab_ = ANDROID_LIBDL_STRTAB;
+ __libdl_info->symtab_ = g_libdl_symtab;
+ __libdl_info->nbucket_ = sizeof(g_libdl_buckets)/sizeof(unsigned);
+ __libdl_info->nchain_ = sizeof(g_libdl_chains)/sizeof(unsigned);
+ __libdl_info->bucket_ = g_libdl_buckets;
+ __libdl_info->chain_ = g_libdl_chains;
+ __libdl_info->ref_count_ = 1;
+ __libdl_info->strtab_size_ = sizeof(ANDROID_LIBDL_STRTAB);
+ __libdl_info->local_group_root_ = __libdl_info;
+ __libdl_info->soname_ = "ld-android.so";
+ __libdl_info->target_sdk_version_ = __ANDROID_API__;
+ __libdl_info->generate_handle();
+ __libdl_info->link_map_head.l_addr = linker_map.l_addr;
+ __libdl_info->link_map_head.l_name = linker_map.l_name;
+ __libdl_info->link_map_head.l_ld = linker_map.l_ld;
+#if DISABLED_FOR_HYBRIS_SUPPORT
+#if defined(__work_around_b_24465209__)
+ strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
+#endif
+#endif
+ }
+
+ return __libdl_info;
+}
+
+// hybris compat
+extern "C" {
+void* android_dlopen(const char* filename, int flag) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __dlopen(filename, flag, caller_addr);
+}
+
+char* android_dlerror() {
+ return __dlerror();
+}
+
+void* android_dlsym(void* handle, const char* symbol) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __dlsym(handle, symbol, caller_addr);
+}
+
+void* android_dlvsym(void* handle, const char* symbol, const char* version) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __dlvsym(handle, symbol, version, caller_addr);
+}
+
+int android_dladdr(const void* addr, Dl_info* info) {
+ return __dladdr(addr, info);
+}
+
+int android_dlclose(void* handle) {
+ return __dlclose(handle);
+}
+
+#if defined(__arm__)
+_Unwind_Ptr android_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
+ return __android_dl_unwind_find_exidx(pc, pcount);
+}
+#endif
+
+int android_dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data), void* data) {
+ return __android_dl_iterate_phdr(cb, data);
+}
+
+void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
+ __android_get_LD_LIBRARY_PATH(buffer, buffer_size);
+}
+
+void android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
+ __android_update_LD_LIBRARY_PATH(ld_library_path);
+}
+
+void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __android_dlopen_ext(filename, flag, extinfo, caller_addr);
+}
+
+void android_set_application_target_sdk_version(uint32_t target) {
+ __android_set_application_target_sdk_version(target);
+}
+uint32_t android_get_application_target_sdk_version() {
+ return __android_get_application_target_sdk_version();
+}
+
+bool android_init_anonymous_namespace(const char* shared_libs_sonames,
+ const char* library_search_path) {
+ return __android_init_anonymous_namespace(shared_libs_sonames, library_search_path);
+}
+
+struct android_namespace_t* android_create_namespace(const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ struct android_namespace_t* parent) {
+ const void* caller_addr = __builtin_return_address(0);
+ return __android_create_namespace(name,
+ ld_library_path,
+ default_library_path,
+ type,
+ permitted_when_isolated_path,
+ parent,
+ caller_addr);
+}
+
+bool android_link_namespaces(struct android_namespace_t* namespace_from,
+ struct android_namespace_t* namespace_to,
+ const char* shared_libs_sonames) {
+ return __android_link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
+}
+
+void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
+ __android_dlwarning(obj, f);
+}
+
+struct android_namespace_t* android_get_exported_namespace(const char* name) {
+ return __android_get_exported_namespace(name);
+}
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/hybris_compat.cpp
^
|
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hybris_compat.h"
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/hybris_compat.h
^
|
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef HYBRIS_ANDROID_MM_COMPAT_H_
+#define HYBRIS_ANDROID_MM_COMPAT_H_
+
+#include <string.h>
+#include <memory.h>
+
+extern "C" size_t strlcpy(char *dest, const char *src, size_t size);
+extern "C" size_t strlcat(char *dst, const char *src, size_t size);
+
+#define ELF_ST_BIND(x) ((x) >> 4)
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+/*
+ * From bionic/libc/include/elf.h
+ *
+ * Android compressed rel/rela sections
+ */
+#define DT_ANDROID_REL (DT_LOOS + 2)
+#define DT_ANDROID_RELSZ (DT_LOOS + 3)
+
+#define DT_ANDROID_RELA (DT_LOOS + 4)
+#define DT_ANDROID_RELASZ (DT_LOOS + 5)
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/ld.config.format.md
^
|
@@ -0,0 +1,83 @@
+# Linker config file format
+
+This document describes format of /system/etc/ld.config.txt file. This file can be used to customize
+linker-namespace setup for dynamic executables.
+
+## Overview
+
+The configuration consists of 2 parts
+1. Mappings - maps executable locations to sections
+2. Sections - contains linker-namespace configuration
+
+## Mappings
+
+This part of the document maps location of an executable to a section. Here is an example
+
+The format is `dir.<section_name>=<directory>`
+
+The mappings should be defined between start of ld.config.txt and the first section.
+
+## Section
+
+Every section starts with `[section_name]` (which is used in mappings) and it defines namespaces
+configuration using set of properties described in example below.
+
+## Example
+
+```
+# The following line maps section to a dir. Binraies ran from this location will use namespaces
+# configuration specified in [example_section] below
+dir.example_section=/system/bin/example
+
+# Section starts
+[example_section]
+
+# When this flag is set to true linker will set target_sdk_version for this binary to
+# the version specified in <dirname>/.version file, where <dirname> = dirname(executable_path)
+#
+# default value is false
+enable.target.sdk.version = true
+
+# This property can be used to declare additional namespaces.Note that there is always the default
+# namespace. The default namespace is the namespace for the main executable. This list is
+# comma-separated.
+additional.namespaces = ns1
+
+# Each namespace property starts with "namespace.<namespace-name>" The following is configuration
+# for the default namespace
+
+# Is namespace isolated - the default value is false
+namespace.default.isolated = true
+
+# Default namespace search path. Note that ${LIB} here is substituted with "lib" for 32bit targets
+# and with "lib64" for 64bit ones.
+namespace.default.search.paths = /system/${LIB}:/system/other/${LIB}
+
+# ... same for asan
+namespace.default.asan.search.paths = /data/${LIB}:/data/other/${LIB}
+
+# Permitted path
+namespace.default.permitted.paths = /system/${LIB}
+
+# ... asan
+namespace.default.asan.permitted.paths = /data/${LIB}
+
+# This declares linked namespaces - comma separated list.
+namespace.default.links = ns1
+
+# For every link define list of shared libraries. This is list of the libraries accessilbe from
+# default namespace but loaded in the linked namespace.
+namespace.default.link.ns1.shared_libs = libexternal.so:libother.so
+
+# This part defines config for ns1
+namespace.ns1.isolated = true
+namespace.ns1.search.paths = /vendor/${LIB}
+namespace.ns1.asan.search.paths = /data/vendor/${LIB}
+namespace.ns1.permitted.paths = /vendor/${LIB}
+namespace.ns1.asan.permitted.paths = /data/vendor/${LIB}
+
+# and links it to default namespace
+namespace.ns.links = default
+namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
+```
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linked_list.h
^
|
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKED_LIST_H
+#define __LINKED_LIST_H
+
+#include "private/bionic_macros.h"
+
+template<typename T>
+struct LinkedListEntry {
+ LinkedListEntry<T>* next;
+ T* element;
+};
+
+// ForwardInputIterator
+template<typename T>
+class LinkedListIterator {
+ public:
+ LinkedListIterator() : entry_(nullptr) {}
+ LinkedListIterator(const LinkedListIterator<T>& that) : entry_(that.entry_) {}
+ explicit LinkedListIterator(LinkedListEntry<T>* entry) : entry_(entry) {}
+
+ LinkedListIterator<T>& operator=(const LinkedListIterator<T>& that) {
+ entry_ = that.entry_;
+ return *this;
+ }
+
+ LinkedListIterator<T>& operator++() {
+ entry_ = entry_->next;
+ return *this;
+ }
+
+ T* const operator*() {
+ return entry_->element;
+ }
+
+ bool operator==(const LinkedListIterator<T>& that) const {
+ return entry_ == that.entry_;
+ }
+
+ bool operator!=(const LinkedListIterator<T>& that) const {
+ return entry_ != that.entry_;
+ }
+
+ private:
+ LinkedListEntry<T> *entry_;
+};
+
+/*
+ * Represents linked list of objects of type T
+ */
+template<typename T, typename Allocator>
+class LinkedList {
+ public:
+ typedef LinkedListIterator<T> iterator;
+ typedef T* value_type;
+
+ LinkedList() : head_(nullptr), tail_(nullptr) {}
+ ~LinkedList() {
+ clear();
+ }
+
+ LinkedList(LinkedList&& that) {
+ this->head_ = that.head_;
+ this->tail_ = that.tail_;
+ that.head_ = that.tail_ = nullptr;
+ }
+
+ void push_front(T* const element) {
+ LinkedListEntry<T>* new_entry = Allocator::alloc();
+ new_entry->next = head_;
+ new_entry->element = element;
+ head_ = new_entry;
+ if (tail_ == nullptr) {
+ tail_ = new_entry;
+ }
+ }
+
+ void push_back(T* const element) {
+ LinkedListEntry<T>* new_entry = Allocator::alloc();
+ new_entry->next = nullptr;
+ new_entry->element = element;
+ if (tail_ == nullptr) {
+ tail_ = head_ = new_entry;
+ } else {
+ tail_->next = new_entry;
+ tail_ = new_entry;
+ }
+ }
+
+ T* pop_front() {
+ if (head_ == nullptr) {
+ return nullptr;
+ }
+
+ LinkedListEntry<T>* entry = head_;
+ T* element = entry->element;
+ head_ = entry->next;
+ Allocator::free(entry);
+
+ if (head_ == nullptr) {
+ tail_ = nullptr;
+ }
+
+ return element;
+ }
+
+ T* front() const {
+ if (head_ == nullptr) {
+ return nullptr;
+ }
+
+ return head_->element;
+ }
+
+ void clear() {
+ while (head_ != nullptr) {
+ LinkedListEntry<T>* p = head_;
+ head_ = head_->next;
+ Allocator::free(p);
+ }
+
+ tail_ = nullptr;
+ }
+
+ bool empty() {
+ return (head_ == nullptr);
+ }
+
+ template<typename F>
+ void for_each(F action) const {
+ visit([&] (T* si) {
+ action(si);
+ return true;
+ });
+ }
+
+ template<typename F>
+ bool visit(F action) const {
+ for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+ if (!action(e->element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template<typename F>
+ void remove_if(F predicate) {
+ for (LinkedListEntry<T>* e = head_, *p = nullptr; e != nullptr;) {
+ if (predicate(e->element)) {
+ LinkedListEntry<T>* next = e->next;
+ if (p == nullptr) {
+ head_ = next;
+ } else {
+ p->next = next;
+ }
+
+ if (tail_ == e) {
+ tail_ = p;
+ }
+
+ Allocator::free(e);
+
+ e = next;
+ } else {
+ p = e;
+ e = e->next;
+ }
+ }
+ }
+
+ void remove(T* element) {
+ remove_if([&](T* e) {
+ return e == element;
+ });
+ }
+
+ template<typename F>
+ T* find_if(F predicate) const {
+ for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+ if (predicate(e->element)) {
+ return e->element;
+ }
+ }
+
+ return nullptr;
+ }
+
+ iterator begin() const {
+ return iterator(head_);
+ }
+
+ iterator end() const {
+ return iterator(nullptr);
+ }
+
+ iterator find(T* value) const {
+ for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+ if (e->element == value) {
+ return iterator(e);
+ }
+ }
+
+ return end();
+ }
+
+ size_t copy_to_array(T* array[], size_t array_length) const {
+ size_t sz = 0;
+ for (LinkedListEntry<T>* e = head_; sz < array_length && e != nullptr; e = e->next) {
+ array[sz++] = e->element;
+ }
+
+ return sz;
+ }
+
+ bool contains(const T* el) const {
+ for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+ if (e->element == el) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static LinkedList make_list(T* const element) {
+ LinkedList<T, Allocator> one_element_list;
+ one_element_list.push_back(element);
+ return one_element_list;
+ }
+
+ private:
+ LinkedListEntry<T>* head_;
+ LinkedListEntry<T>* tail_;
+ DISALLOW_COPY_AND_ASSIGN(LinkedList);
+};
+
+#endif // __LINKED_LIST_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker.cpp
^
|
@@ -0,0 +1,3735 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <android/api-level.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+
+#include <new>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "hybris_compat.h"
+
+#include <android-base/scopeguard.h>
+
+#include <async_safe/log.h>
+
+// Private C library headers.
+
+#include "linker.h"
+#include "linker_block_allocator.h"
+#include "linker_cfi.h"
+#include "linker_config.h"
+#include "linker_gdb_support.h"
+#include "linker_globals.h"
+#include "linker_debug.h"
+#include "linker_dlwarning.h"
+#include "linker_main.h"
+#include "linker_namespaces.h"
+#include "linker_sleb128.h"
+#include "linker_phdr.h"
+#include "linker_relocs.h"
+#include "linker_reloc_iterators.h"
+#include "linker_utils.h"
+
+//#include "android-base/strings.h"
+//#include "android-base/stringprintf.h"
+//#include "ziparchive/zip_archive.h"
+
+#ifdef WANT_ARM_TRACING
+#include "../wrappers.h"
+#endif
+
+// Stay compatible with newer glibc
+#ifndef R_AARCH64_TLS_TPREL64
+#define R_AARCH64_TLS_TPREL64 R_AARCH64_TLS_TPREL
+#endif
+#ifndef R_AARCH64_TLS_DTPREL32
+#define R_AARCH64_TLS_DTPREL32 R_AARCH64_TLS_DTPREL
+#endif
+
+#define TMPFS_MAGIC 0x01021994
+
+#define DF_1_PIE 0x08000000
+
+// Override macros to use C++ style casts.
+#undef ELF_ST_TYPE
+#define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
+
+static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
+static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
+android_namespace_t *g_default_namespace = new (g_namespace_allocator.alloc()) android_namespace_t();
+
+static android_namespace_t* g_anonymous_namespace = g_default_namespace;
+static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
+
+static LinkerTypeAllocator<soinfo> g_soinfo_allocator;
+static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
+
+static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
+
+#if defined(__LP64__)
+static const char* const kSystemLibDir = "/system/lib64";
+static const char* const kVendorLibDir = "/vendor/lib64";
+static const char* const kVendorLibEglDir = "/vendor/lib64/egl";
+static const char* const kOdmLibDir = "/odm/lib64";
+static const char* const kOdmLibEglDir = "/odm/lib64/egl";
+#ifdef HAS_ANDROID_9_0_0
+static const char* const kSystemLibVndk28Dir = "/system/lib64/vndk-28";
+#endif
+static const char* const kAsanSystemLibDir = "/data/asan/system/lib64";
+static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib64";
+static const char* const kAsanVendorLibEglDir = "/data/asan/vendor/lib64/egl";
+static const char* const kAsanOdmLibDir = "/data/asan/odm/lib64";
+static const char* const kAsanOdmLibEglDir = "/data/asan/odm/lib64/egl";
+#ifdef HAS_ANDROID_9_0_0
+static const char* const kAsanSystemLibVndk28Dir = "/data/asan/system/lib64/vndk-28";
+#endif
+#else
+static const char* const kSystemLibDir = "/system/lib";
+static const char* const kVendorLibDir = "/vendor/lib";
+static const char* const kVendorLibEglDir = "/vendor/lib/egl";
+static const char* const kOdmLibDir = "/odm/lib";
+static const char* const kOdmLibEglDir = "/odm/lib/egl";
+#ifdef HAS_ANDROID_9_0_0
+static const char* const kSystemLibVndk28Dir = "/system/lib/vndk-28";
+#endif
+static const char* const kAsanSystemLibDir = "/data/asan/system/lib";
+static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib";
+static const char* const kAsanVendorLibEglDir = "/data/asan/vendor/lib/egl";
+static const char* const kAsanOdmLibDir = "/data/asan/odm/lib";
+static const char* const kAsanOdmLibEglDir = "/data/asan/odm/lib/egl";
+#ifdef HAS_ANDROID_9_0_0
+static const char* const kAsanSystemLibVndk28Dir = "/data/asan/system/lib/vndk-28";
+#endif
+#endif
+
+static const char* const kAsanLibDirPrefix = "/data/asan";
+
+static const char* const kDefaultLdPaths[] = {
+ kSystemLibDir,
+ kOdmLibDir,
+ kVendorLibDir,
+
+ // libhybris support:
+ kOdmLibEglDir,
+ kVendorLibEglDir,
+
+#ifdef HAS_ANDROID_9_0_0
+ kSystemLibVndk28Dir,
+#endif
+ nullptr
+};
+
+static const char* const kAsanDefaultLdPaths[] = {
+ kAsanSystemLibDir,
+ kSystemLibDir,
+ kAsanOdmLibDir,
+ kOdmLibDir,
+ kAsanVendorLibDir,
+ kVendorLibDir,
+
+ // libhybris support:
+ kAsanOdmLibEglDir,
+ kOdmLibEglDir,
+ kAsanVendorLibEglDir,
+ kVendorLibEglDir,
+
+#ifdef HAS_ANDROID_9_0_0
+ kAsanSystemLibVndk28Dir,
+ kSystemLibVndk28Dir,
+#endif
+ nullptr
+};
+
+// Is ASAN enabled?
+static bool g_is_asan = false;
+
+static CFIShadowWriter g_cfi_shadow;
+
+CFIShadowWriter* get_cfi_shadow() {
+ return &g_cfi_shadow;
+}
+
+static bool is_system_library(const std::string& realpath) {
+ for (const auto& dir : g_default_namespace->get_default_library_paths()) {
+ if (file_is_in_dir(realpath, dir)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if the file exists and not a directory.
+static bool file_exists(const char* path) {
+ struct stat s;
+
+ if (stat(path, &s) != 0) {
+ return false;
+ }
+
+ return S_ISREG(s.st_mode);
+}
+
+static std::string resolve_soname(const std::string& name) {
+ // We assume that soname equals to basename here
+
+ // TODO(dimitry): consider having honest absolute-path -> soname resolution
+ // note that since we might end up refusing to load this library because
+ // it is not in shared libs list we need to get the soname without actually loading
+ // the library.
+ //
+ // On the other hand there are several places where we already assume that
+ // soname == basename in particular for any not-loaded library mentioned
+ // in DT_NEEDED list.
+ return basename(name.c_str());
+}
+
+static bool maybe_accessible_via_namespace_links(android_namespace_t* ns, const char* name) {
+ std::string soname = resolve_soname(name);
+ for (auto& ns_link : ns->linked_namespaces()) {
+ if (ns_link.is_accessible(soname.c_str())) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
+// gradually remove libraries from this list until it is gone.
+static bool is_greylisted(android_namespace_t* ns, const char* name, const soinfo* needed_by) {
+ static const char* const kLibraryGreyList[] = {
+ "libandroid_runtime.so",
+ "libbinder.so",
+ "libcrypto.so",
+ "libcutils.so",
+ "libexpat.so",
+ "libgui.so",
+ "libmedia.so",
+ "libnativehelper.so",
+ "libskia.so",
+ "libssl.so",
+ "libstagefright.so",
+ "libsqlite.so",
+ "libui.so",
+ "libutils.so",
+ "libvorbisidec.so",
+ nullptr
+ };
+
+ // If you're targeting N, you don't get the greylist.
+ if (g_greylist_disabled || get_application_target_sdk_version() >= __ANDROID_API_N__) {
+ return false;
+ }
+
+ // if the library needed by a system library - implicitly assume it
+ // is greylisted unless it is in the list of shared libraries for one or
+ // more linked namespaces
+ if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
+ return !maybe_accessible_via_namespace_links(ns, name);
+ }
+
+ // if this is an absolute path - make sure it points to /system/lib(64)
+ if (name[0] == '/' && dirname(name) == kSystemLibDir) {
+ // and reduce the path to basename
+ name = basename(name);
+ }
+
+ for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
+ if (strcmp(name, kLibraryGreyList[i]) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+// END OF WORKAROUND
+
+static std::vector<std::string> g_ld_preload_names;
+
+static bool g_anonymous_namespace_initialized;
+
+#if STATS
+struct linker_stats_t {
+ int count[kRelocMax];
+};
+
+static linker_stats_t linker_stats;
+
+void count_relocation(RelocationKind kind) {
+ ++linker_stats.count[kind];
+}
+#else
+void count_relocation(RelocationKind) {
+}
+#endif
+
+#if COUNT_PAGES
+uint32_t bitmask[4096];
+#endif
+
+static void notify_gdb_of_load(soinfo* info) {
+ if (info->is_linker() || info->is_main_executable()) {
+ // gdb already knows about the linker and the main executable.
+ return;
+ }
+
+ link_map* map = &(info->link_map_head);
+
+ map->l_addr = info->load_bias;
+ // link_map l_name field is not const.
+ map->l_name = const_cast<char*>(info->get_realpath());
+ map->l_ld = info->dynamic;
+
+ CHECK(map->l_name != nullptr);
+ CHECK(map->l_name[0] != '\0');
+
+ notify_gdb_of_load(map);
+}
+
+static void notify_gdb_of_unload(soinfo* info) {
+ notify_gdb_of_unload(&(info->link_map_head));
+}
+
+LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
+ return g_soinfo_links_allocator.alloc();
+}
+
+void SoinfoListAllocator::free(LinkedListEntry<soinfo>* entry) {
+ g_soinfo_links_allocator.free(entry);
+}
+
+LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
+ return g_namespace_list_allocator.alloc();
+}
+
+void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
+ g_namespace_list_allocator.free(entry);
+}
+
+soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
+ struct stat* file_stat, off64_t file_offset,
+ uint32_t rtld_flags) {
+ if (strlen(name) >= PATH_MAX) {
+ DL_ERR("library name \"%s\" too long", name);
+ return nullptr;
+ }
+
+ TRACE("name %s: allocating soinfo for ns=%p", name, ns);
+
+ soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
+ file_offset, rtld_flags);
+
+ solist_add_soinfo(si);
+
+ si->generate_handle();
+ ns->add_soinfo(si);
+
+ TRACE("name %s: allocated soinfo @ %p", name, si);
+ return si;
+}
+
+static void soinfo_free(soinfo* si) {
+ if (si == nullptr) {
+ return;
+ }
+
+ if (si->base != 0 && si->size != 0) {
+ if (!si->is_mapped_by_caller()) {
+ munmap(reinterpret_cast<void*>(si->base), si->size);
+ } else {
+ // remap the region as PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE
+ mmap(reinterpret_cast<void*>(si->base), si->size, PROT_NONE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ }
+ }
+
+ TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
+
+ if (!solist_remove_soinfo(si)) {
+ // TODO (dimitry): revisit this - for now preserving the logic
+ // but it does not look right, abort if soinfo is not in the list instead?
+ return;
+ }
+
+ // clear links to/from si
+ si->remove_all_links();
+
+ si->~soinfo();
+ g_soinfo_allocator.free(si);
+}
+
+static void parse_path(const char* path, const char* delimiters,
+ std::vector<std::string>* resolved_paths) {
+ std::vector<std::string> paths;
+ split_path(path, delimiters, &paths);
+ resolve_paths(paths, resolved_paths);
+}
+
+static void parse_LD_LIBRARY_PATH(const char* path) {
+ std::vector<std::string> ld_libary_paths;
+ parse_path(path, ":", &ld_libary_paths);
+ g_default_namespace->set_ld_library_paths(std::move(ld_libary_paths));
+}
+
+static bool realpath_fd(int fd, std::string* realpath) {
+ std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
+ snprintf(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
+ if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
+ PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+ return false;
+ }
+
+ *realpath = &buf[0];
+ return true;
+}
+
+#if defined(__arm__)
+
+// For a given PC, find the .so that it belongs to.
+// Returns the base address of the .ARM.exidx section
+// for that .so, and the number of 8-byte entries
+// in that section (via *pcount).
+//
+// Intended to be called by libc's __gnu_Unwind_Find_exidx().
+_Unwind_Ptr do_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
+ for (soinfo* si = solist_get_head(); si != 0; si = si->next) {
+ if ((pc >= si->base) && (pc < (si->base + si->size))) {
+ *pcount = si->ARM_exidx_count;
+ return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
+ }
+ }
+ *pcount = 0;
+ return 0;
+}
+
+#endif
+
+// Here, we only have to provide a callback to iterate across all the
+// loaded libraries. gcc_eh does the rest.
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
+ int rv = 0;
+ for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
+ dl_phdr_info dl_info;
+ dl_info.dlpi_addr = si->link_map_head.l_addr;
+ dl_info.dlpi_name = si->link_map_head.l_name;
+ dl_info.dlpi_phdr = si->phdr;
+ dl_info.dlpi_phnum = si->phnum;
+ rv = cb(&dl_info, sizeof(dl_phdr_info), data);
+ if (rv != 0) {
+ break;
+ }
+ }
+ return rv;
+}
+
+
+bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
+ soinfo** si_found_in, const soinfo_list_t& global_group,
+ const soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
+ SymbolName symbol_name(name);
+ const ElfW(Sym)* s = nullptr;
+
+ /* "This element's presence in a shared object library alters the dynamic linker's
+ * symbol resolution algorithm for references within the library. Instead of starting
+ * a symbol search with the executable file, the dynamic linker starts from the shared
+ * object itself. If the shared object fails to supply the referenced symbol, the
+ * dynamic linker then searches the executable file and other shared objects as usual."
+ *
+ * http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html
+ *
+ * Note that this is unlikely since static linker avoids generating
+ * relocations for -Bsymbolic linked dynamic executables.
+ */
+ if (si_from->has_DT_SYMBOLIC) {
+ DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
+ if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
+ return false;
+ }
+
+ if (s != nullptr) {
+ *si_found_in = si_from;
+ }
+ }
+
+ // 1. Look for it in global_group
+ if (s == nullptr) {
+ bool error = false;
+ global_group.visit([&](soinfo* global_si) {
+ DEBUG("%s: looking up %s in %s (from global group)",
+ si_from->get_realpath(), name, global_si->get_realpath());
+ if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
+ error = true;
+ return false;
+ }
+
+ if (s != nullptr) {
+ *si_found_in = global_si;
+ return false;
+ }
+
+ return true;
+ });
+
+ if (error) {
+ return false;
+ }
+ }
+
+ // 2. Look for it in the local group
+ if (s == nullptr) {
+ bool error = false;
+ local_group.visit([&](soinfo* local_si) {
+ if (local_si == si_from && si_from->has_DT_SYMBOLIC) {
+ // we already did this - skip
+ return true;
+ }
+
+ DEBUG("%s: looking up %s in %s (from local group)",
+ si_from->get_realpath(), name, local_si->get_realpath());
+ if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
+ error = true;
+ return false;
+ }
+
+ if (s != nullptr) {
+ *si_found_in = local_si;
+ return false;
+ }
+
+ return true;
+ });
+
+ if (error) {
+ return false;
+ }
+ }
+
+ if (s != nullptr) {
+ TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
+ "found in %s, base = %p, load bias = %p",
+ si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
+ (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
+ reinterpret_cast<void*>((*si_found_in)->load_bias));
+ }
+
+ *symbol = s;
+ return true;
+}
+
+ProtectedDataGuard::ProtectedDataGuard() {
+ if (ref_count_++ == 0) {
+ protect_data(PROT_READ | PROT_WRITE);
+ }
+
+ if (ref_count_ == 0) { // overflow
+ async_safe_fatal("Too many nested calls to dlopen()");
+ }
+}
+
+ProtectedDataGuard::~ProtectedDataGuard() {
+ if (--ref_count_ == 0) {
+ protect_data(PROT_READ);
+ }
+}
+
+void ProtectedDataGuard::protect_data(int protection) {
+ g_soinfo_allocator.protect_all(protection);
+ g_soinfo_links_allocator.protect_all(protection);
+ g_namespace_allocator.protect_all(protection);
+ g_namespace_list_allocator.protect_all(protection);
+}
+
+size_t ProtectedDataGuard::ref_count_ = 0;
+
+// Each size has it's own allocator.
+template<size_t size>
+class SizeBasedAllocator {
+ public:
+ static void* alloc() {
+ return allocator_.alloc();
+ }
+
+ static void free(void* ptr) {
+ allocator_.free(ptr);
+ }
+
+ private:
+ static LinkerBlockAllocator allocator_;
+};
+
+template<size_t size>
+LinkerBlockAllocator SizeBasedAllocator<size>::allocator_(size);
+
+template<typename T>
+class TypeBasedAllocator {
+ public:
+ static T* alloc() {
+ return reinterpret_cast<T*>(SizeBasedAllocator<sizeof(T)>::alloc());
+ }
+
+ static void free(T* ptr) {
+ SizeBasedAllocator<sizeof(T)>::free(ptr);
+ }
+};
+
+class LoadTask {
+ public:
+ struct deleter_t {
+ void operator()(LoadTask* t) {
+ t->~LoadTask();
+ TypeBasedAllocator<LoadTask>::free(t);
+ }
+ };
+
+ static deleter_t deleter;
+
+ static LoadTask* create(const char* name,
+ soinfo* needed_by,
+ android_namespace_t* start_from,
+ std::unordered_map<const soinfo*, ElfReader>* readers_map) {
+ LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
+ return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
+ }
+
+ const char* get_name() const {
+ return name_;
+ }
+
+ soinfo* get_needed_by() const {
+ return needed_by_;
+ }
+
+ soinfo* get_soinfo() const {
+ return si_;
+ }
+
+ void set_soinfo(soinfo* si) {
+ si_ = si;
+ }
+
+ off64_t get_file_offset() const {
+ return file_offset_;
+ }
+
+ void set_file_offset(off64_t offset) {
+ file_offset_ = offset;
+ }
+
+ int get_fd() const {
+ return fd_;
+ }
+
+ void set_fd(int fd, bool assume_ownership) {
+ fd_ = fd;
+ close_fd_ = assume_ownership;
+ }
+
+ const android_dlextinfo* get_extinfo() const {
+ return extinfo_;
+ }
+
+ void set_extinfo(const android_dlextinfo* extinfo) {
+ extinfo_ = extinfo;
+ }
+
+ bool is_dt_needed() const {
+ return is_dt_needed_;
+ }
+
+ void set_dt_needed(bool is_dt_needed) {
+ is_dt_needed_ = is_dt_needed;
+ }
+
+ // returns the namespace from where we need to start loading this.
+ const android_namespace_t* get_start_from() const {
+ return start_from_;
+ }
+
+ const ElfReader& get_elf_reader() const {
+ CHECK(si_ != nullptr);
+ return (*elf_readers_map_)[si_];
+ }
+
+ ElfReader& get_elf_reader() {
+ CHECK(si_ != nullptr);
+ return (*elf_readers_map_)[si_];
+ }
+
+ std::unordered_map<const soinfo*, ElfReader>* get_readers_map() {
+ return elf_readers_map_;
+ }
+
+ bool read(const char* realpath, off64_t file_size) {
+ ElfReader& elf_reader = get_elf_reader();
+ return elf_reader.Read(realpath, fd_, file_offset_, file_size);
+ }
+
+ bool load() {
+ ElfReader& elf_reader = get_elf_reader();
+ if (!elf_reader.Load(extinfo_)) {
+ return false;
+ }
+
+ si_->base = elf_reader.load_start();
+ si_->size = elf_reader.load_size();
+ si_->set_mapped_by_caller(elf_reader.is_mapped_by_caller());
+ si_->load_bias = elf_reader.load_bias();
+ si_->phnum = elf_reader.phdr_count();
+ si_->phdr = elf_reader.loaded_phdr();
+
+ return true;
+ }
+
+ private:
+ LoadTask(const char* name,
+ soinfo* needed_by,
+ android_namespace_t* start_from,
+ std::unordered_map<const soinfo*, ElfReader>* readers_map)
+ : name_(name), needed_by_(needed_by), si_(nullptr),
+ fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
+ is_dt_needed_(false), start_from_(start_from) {}
+
+ ~LoadTask() {
+ if (fd_ != -1 && close_fd_) {
+ close(fd_);
+ }
+ }
+
+ const char* name_;
+ soinfo* needed_by_;
+ soinfo* si_;
+ const android_dlextinfo* extinfo_;
+ int fd_;
+ bool close_fd_;
+ off64_t file_offset_;
+ std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
+ // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
+ bool is_dt_needed_;
+ // END OF WORKAROUND
+ const android_namespace_t* const start_from_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
+};
+
+LoadTask::deleter_t LoadTask::deleter;
+
+template <typename T>
+using linked_list_t = LinkedList<T, TypeBasedAllocator<LinkedListEntry<T>>>;
+
+typedef linked_list_t<soinfo> SoinfoLinkedList;
+typedef linked_list_t<const char> StringLinkedList;
+typedef std::vector<LoadTask*> LoadTaskList;
+
+enum walk_action_result_t : uint32_t {
+ kWalkStop = 0,
+ kWalkContinue = 1,
+ kWalkSkip = 2
+};
+
+// This function walks down the tree of soinfo dependencies
+// in breadth-first order and
+// * calls action(soinfo* si) for each node, and
+// * terminates walk if action returns kWalkStop
+// * skips children of the node if action
+// return kWalkSkip
+//
+// walk_dependencies_tree returns false if walk was terminated
+// by the action and true otherwise.
+template<typename F>
+static bool walk_dependencies_tree(soinfo* root_soinfos[], size_t root_soinfos_size, F action) {
+ SoinfoLinkedList visit_list;
+ SoinfoLinkedList visited;
+
+ for (size_t i = 0; i < root_soinfos_size; ++i) {
+ visit_list.push_back(root_soinfos[i]);
+ }
+
+ soinfo* si;
+ while ((si = visit_list.pop_front()) != nullptr) {
+ if (visited.contains(si)) {
+ continue;
+ }
+
+ walk_action_result_t result = action(si);
+
+ if (result == kWalkStop) {
+ return false;
+ }
+
+ visited.push_back(si);
+
+ if (result != kWalkSkip) {
+ si->get_children().for_each([&](soinfo* child) {
+ visit_list.push_back(child);
+ });
+ }
+ }
+
+ return true;
+}
+
+
+static const ElfW(Sym)* dlsym_handle_lookup(android_namespace_t* ns,
+ soinfo* root,
+ soinfo* skip_until,
+ soinfo** found,
+ SymbolName& symbol_name,
+ const version_info* vi) {
+ const ElfW(Sym)* result = nullptr;
+ bool skip_lookup = skip_until != nullptr;
+
+ walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
+ if (skip_lookup) {
+ skip_lookup = current_soinfo != skip_until;
+ return kWalkContinue;
+ }
+
+ if (!ns->is_accessible(current_soinfo)) {
+ return kWalkSkip;
+ }
+
+ if (!current_soinfo->find_symbol_by_name(symbol_name, vi, &result)) {
+ result = nullptr;
+ return kWalkStop;
+ }
+
+ if (result != nullptr) {
+ *found = current_soinfo;
+ return kWalkStop;
+ }
+
+ return kWalkContinue;
+ });
+
+ return result;
+}
+
+static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
+ const char* name,
+ const version_info* vi,
+ soinfo** found,
+ soinfo* caller,
+ void* handle);
+
+// This is used by dlsym(3). It performs symbol lookup only within the
+// specified soinfo object and its dependencies in breadth first order.
+static const ElfW(Sym)* dlsym_handle_lookup(soinfo* si,
+ soinfo** found,
+ const char* name,
+ const version_info* vi) {
+ // According to man dlopen(3) and posix docs in the case when si is handle
+ // of the main executable we need to search not only in the executable and its
+ // dependencies but also in all libraries loaded with RTLD_GLOBAL.
+ //
+ // Since RTLD_GLOBAL is always set for the main executable and all dt_needed shared
+ // libraries and they are loaded in breath-first (correct) order we can just execute
+ // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup.
+ if (si == solist_get_somain()) {
+ return dlsym_linear_lookup(g_default_namespace, name, vi, found, nullptr, RTLD_DEFAULT);
+ }
+
+ SymbolName symbol_name(name);
+ // note that the namespace is not the namespace associated with caller_addr
+ // we use ns associated with root si intentionally here. Using caller_ns
+ // causes problems when user uses dlopen_ext to open a library in the separate
+ // namespace and then calls dlsym() on the handle.
+ return dlsym_handle_lookup(si->get_primary_namespace(), si, nullptr, found, symbol_name, vi);
+}
+
+/* This is used by dlsym(3) to performs a global symbol lookup. If the
+ start value is null (for RTLD_DEFAULT), the search starts at the
+ beginning of the global solist. Otherwise the search starts at the
+ specified soinfo (for RTLD_NEXT).
+ */
+static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
+ const char* name,
+ const version_info* vi,
+ soinfo** found,
+ soinfo* caller,
+ void* handle) {
+ SymbolName symbol_name(name);
+
+ auto& soinfo_list = ns->soinfo_list();
+ auto start = soinfo_list.begin();
+
+ if (handle == RTLD_NEXT) {
+ if (caller == nullptr) {
+ return nullptr;
+ } else {
+ auto it = soinfo_list.find(caller);
+ CHECK (it != soinfo_list.end());
+ start = ++it;
+ }
+ }
+
+ const ElfW(Sym)* s = nullptr;
+ for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
+ soinfo* si = *it;
+ // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
+ // if the library is opened by application with target api level < M.
+ // See http://b/21565766
+ if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0 &&
+ si->get_target_sdk_version() >= __ANDROID_API_M__) {
+ continue;
+ }
+
+ if (!si->find_symbol_by_name(symbol_name, vi, &s)) {
+ return nullptr;
+ }
+
+ if (s != nullptr) {
+ *found = si;
+ break;
+ }
+ }
+
+ // If not found - use dlsym_handle_lookup for caller's
+ // local_group unless it is part of the global group in which
+ // case we already did it.
+ if (s == nullptr && caller != nullptr &&
+ (caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
+ soinfo* local_group_root = caller->get_local_group_root();
+
+ return dlsym_handle_lookup(local_group_root->get_primary_namespace(),
+ local_group_root,
+ (handle == RTLD_NEXT) ? caller : nullptr,
+ found,
+ symbol_name,
+ vi);
+ }
+
+ if (s != nullptr) {
+ TRACE_TYPE(LOOKUP, "%s s->st_value = %p, found->base = %p",
+ name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
+ }
+
+ return s;
+}
+
+soinfo* find_containing_library(const void* p) {
+ ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
+ for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
+ if (address >= si->base && address - si->base < si->size) {
+ return si;
+ }
+ }
+ return nullptr;
+}
+
+
+class ZipArchiveCache {
+ public:
+ ZipArchiveCache() {}
+ ~ZipArchiveCache();
+
+ //bool get_or_open(const char* zip_path, ZipArchiveHandle* handle);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ZipArchiveCache);
+
+ //std::unordered_map<std::string, ZipArchiveHandle> cache_;
+};
+
+/*
+bool ZipArchiveCache::get_or_open(const char* zip_path, ZipArchiveHandle* handle) {
+ std::string key(zip_path);
+
+ auto it = cache_.find(key);
+ if (it != cache_.end()) {
+ *handle = it->second;
+ return true;
+ }
+
+ int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
+ if (fd == -1) {
+ return false;
+ }
+
+ if (OpenArchiveFd(fd, "", handle) != 0) {
+ // invalid zip-file (?)
+ CloseArchive(handle);
+ close(fd);
+ return false;
+ }
+
+ cache_[key] = *handle;
+ return true;
+}
+*/
+
+ZipArchiveCache::~ZipArchiveCache() {
+/*
+ for (const auto& it : cache_) {
+ CloseArchive(it.second);
+ }
+*/
+}
+
+/*
+static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
+ const char* const input_path,
+ off64_t* file_offset, std::string* realpath) {
+ std::string normalized_path;
+ if (!normalize_path(input_path, &normalized_path)) {
+ return -1;
+ }
+
+ const char* const path = normalized_path.c_str();
+ TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
+
+ // Treat an '!/' separator inside a path as the separator between the name
+ // of the zip file on disk and the subdirectory to search within it.
+ // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
+ // "bar/bas/x.so" within "foo.zip".
+ const char* const separator = strstr(path, kZipFileSeparator);
+ if (separator == nullptr) {
+ return -1;
+ }
+
+ char buf[512];
+ if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
+ PRINT("Warning: ignoring very long library path: %s", path);
+ return -1;
+ }
+
+ buf[separator - path] = '\0';
+
+ const char* zip_path = buf;
+ const char* file_path = &buf[separator - path + 2];
+ int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
+ if (fd == -1) {
+ return -1;
+ }
+
+ ZipArchiveHandle handle;
+ if (!zip_archive_cache->get_or_open(zip_path, &handle)) {
+ // invalid zip-file (?)
+ close(fd);
+ return -1;
+ }
+
+ ZipEntry entry;
+
+ if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
+ // Entry was not found.
+ close(fd);
+ return -1;
+ }
+
+ // Check if it is properly stored
+ if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
+ close(fd);
+ return -1;
+ }
+
+ *file_offset = entry.offset;
+
+ if (realpath_fd(fd, realpath)) {
+ *realpath += separator;
+ } else {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
+ normalized_path.c_str());
+ *realpath = normalized_path;
+ }
+
+ return fd;
+}
+*/
+
+static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) {
+ int n = snprintf(buf, buf_size, "%s/%s", path, name);
+ if (n < 0 || n >= static_cast<int>(buf_size)) {
+ PRINT("Warning: ignoring very long library path: %s/%s", path, name);
+ return false;
+ }
+
+ return true;
+}
+
+static int open_library_on_paths(ZipArchiveCache* zip_archive_cache,
+ const char* name, off64_t* file_offset,
+ const std::vector<std::string>& paths,
+ std::string* realpath) {
+ for (const auto& path : paths) {
+ char buf[512];
+ if (!format_path(buf, sizeof(buf), path.c_str(), name)) {
+ continue;
+ }
+
+ int fd = -1;
+/*
+ if (strstr(buf, kZipFileSeparator) != nullptr) {
+ fd = open_library_in_zipfile(zip_archive_cache, buf, file_offset, realpath);
+ }
+*/
+ if (fd == -1) {
+ fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
+ if (fd != -1) {
+ *file_offset = 0;
+ if (!realpath_fd(fd, realpath)) {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", buf);
+ *realpath = buf;
+ }
+ }
+ }
+
+ if (fd != -1) {
+ return fd;
+ }
+ }
+
+ return -1;
+}
+
+static int open_library(android_namespace_t* ns,
+ ZipArchiveCache* zip_archive_cache,
+ const char* name, soinfo *needed_by,
+ off64_t* file_offset, std::string* realpath) {
+ TRACE("[ opening %s at namespace %s]", name, ns->get_name());
+
+ // If the name contains a slash, we should attempt to open it directly and not search the paths.
+ if (strchr(name, '/') != nullptr) {
+ int fd = -1;
+/*
+ if (strstr(name, kZipFileSeparator) != nullptr) {
+ fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
+ }
+*/
+ if (fd == -1) {
+ fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
+ if (fd != -1) {
+ *file_offset = 0;
+ if (!realpath_fd(fd, realpath)) {
+ PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
+ *realpath = name;
+ }
+ }
+ }
+
+ return fd;
+ }
+
+ // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
+ int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
+ if (fd == -1 && needed_by != nullptr) {
+ fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
+ // Check if the library is accessible
+ if (fd != -1 && !ns->is_accessible(*realpath)) {
+ fd = -1;
+ }
+ }
+
+ if (fd == -1) {
+ fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
+ }
+
+ // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
+ if (fd == -1 && ns->is_greylist_enabled() && is_greylisted(ns, name, needed_by)) {
+ // try searching for it on default_namespace default_library_path
+ fd = open_library_on_paths(zip_archive_cache, name, file_offset,
+ g_default_namespace->get_default_library_paths(), realpath);
+ }
+ // END OF WORKAROUND
+
+ return fd;
+}
+
+const char* fix_dt_needed(const char* dt_needed, const char* sopath) {
+ (void) sopath;
+#if !defined(__LP64__)
+ // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
+ if (get_application_target_sdk_version() < __ANDROID_API_M__) {
+ const char* bname = basename(dt_needed);
+ if (bname != dt_needed) {
+ DL_WARN("library \"%s\" has invalid DT_NEEDED entry \"%s\"", sopath, dt_needed);
+ add_dlwarning(sopath, "invalid DT_NEEDED entry", dt_needed);
+ }
+
+ return bname;
+ }
+#endif
+ return dt_needed;
+}
+
+template<typename F>
+static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
+ for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
+ if (d->d_tag == DT_NEEDED) {
+ action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
+ }
+ }
+}
+
+static bool find_loaded_library_by_inode(android_namespace_t* ns,
+ const struct stat& file_stat,
+ off64_t file_offset,
+ bool search_linked_namespaces,
+ soinfo** candidate) {
+
+ auto predicate = [&](soinfo* si) {
+ return si->get_st_dev() != 0 &&
+ si->get_st_ino() != 0 &&
+ si->get_st_dev() == file_stat.st_dev &&
+ si->get_st_ino() == file_stat.st_ino &&
+ si->get_file_offset() == file_offset;
+ };
+
+ *candidate = ns->soinfo_list().find_if(predicate);
+
+ if (*candidate == nullptr && search_linked_namespaces) {
+ for (auto& link : ns->linked_namespaces()) {
+ android_namespace_t* linked_ns = link.linked_namespace();
+ soinfo* si = linked_ns->soinfo_list().find_if(predicate);
+
+ if (si != nullptr && link.is_accessible(si->get_soname())) {
+ *candidate = si;
+ return true;
+ }
+ }
+ }
+
+ return *candidate != nullptr;
+}
+
+static bool find_loaded_library_by_realpath(android_namespace_t* ns, const char* realpath,
+ bool search_linked_namespaces, soinfo** candidate) {
+ auto predicate = [&](soinfo* si) { return strcmp(realpath, si->get_realpath()) == 0; };
+
+ *candidate = ns->soinfo_list().find_if(predicate);
+
+ if (*candidate == nullptr && search_linked_namespaces) {
+ for (auto& link : ns->linked_namespaces()) {
+ android_namespace_t* linked_ns = link.linked_namespace();
+ soinfo* si = linked_ns->soinfo_list().find_if(predicate);
+
+ if (si != nullptr && link.is_accessible(si->get_soname())) {
+ *candidate = si;
+ return true;
+ }
+ }
+ }
+
+ return *candidate != nullptr;
+}
+
+static bool load_library(android_namespace_t* ns,
+ LoadTask* task,
+ LoadTaskList* load_tasks,
+ int rtld_flags,
+ const std::string& realpath,
+ bool search_linked_namespaces) {
+ off64_t file_offset = task->get_file_offset();
+ const char* name = task->get_name();
+ const android_dlextinfo* extinfo = task->get_extinfo();
+
+ if ((file_offset % PAGE_SIZE) != 0) {
+ DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
+ return false;
+ }
+ if (file_offset < 0) {
+ DL_ERR("file offset for the library \"%s\" is negative: %" PRId64, name, file_offset);
+ return false;
+ }
+
+ struct stat file_stat;
+ if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
+ DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
+ return false;
+ }
+ if (file_offset >= file_stat.st_size) {
+ DL_ERR("file offset for the library \"%s\" >= file size: %" PRId64 " >= %" PRId64,
+ name, file_offset, file_stat.st_size);
+ return false;
+ }
+
+ // Check for symlink and other situations where
+ // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
+ if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
+ soinfo* si = nullptr;
+ if (find_loaded_library_by_inode(ns, file_stat, file_offset, search_linked_namespaces, &si)) {
+ TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
+ "will return existing soinfo", name, si->get_realpath());
+ task->set_soinfo(si);
+ return true;
+ }
+ }
+
+ if ((rtld_flags & RTLD_NOLOAD) != 0) {
+ DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
+ return false;
+ }
+
+ struct statfs fs_stat;
+ if (TEMP_FAILURE_RETRY(fstatfs(task->get_fd(), &fs_stat)) != 0) {
+ DL_ERR("unable to fstatfs file for the library \"%s\": %s", name, strerror(errno));
+ return false;
+ }
+
+ // do not check accessibility using realpath if fd is located on tmpfs
+ // this enables use of memfd_create() for apps
+ if ((fs_stat.f_type != TMPFS_MAGIC) && (!ns->is_accessible(realpath))) {
+ // TODO(dimitry): workaround for http://b/26394120 - the grey-list
+
+ // TODO(dimitry) before O release: add a namespace attribute to have this enabled
+ // only for classloader-namespaces
+ const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
+ if (is_greylisted(ns, name, needed_by)) {
+ // print warning only if needed by non-system library
+ if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
+ const soinfo* needed_or_dlopened_by = task->get_needed_by();
+ const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
+ needed_or_dlopened_by->get_realpath();
+ DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the namespace \"%s\""
+ " - the access is temporarily granted as a workaround for http://b/26394120, note that the access"
+ " will be removed in future releases of Android.",
+ name, realpath.c_str(), sopath, ns->get_name());
+ add_dlwarning(sopath, "unauthorized access to", name);
+ }
+ } else {
+ // do not load libraries if they are not accessible for the specified namespace.
+ const char* needed_or_dlopened_by = task->get_needed_by() == nullptr ?
+ "(unknown)" :
+ task->get_needed_by()->get_realpath();
+
+ DL_ERR("library \"%s\" needed or dlopened by \"%s\" is not accessible for the namespace \"%s\"",
+ name, needed_or_dlopened_by, ns->get_name());
+
+ // do not print this if a library is in the list of shared libraries for linked namespaces
+ if (!maybe_accessible_via_namespace_links(ns, name)) {
+ PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
+ " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
+ " permitted_paths=\"%s\"]",
+ name, realpath.c_str(),
+ needed_or_dlopened_by,
+ ns->get_name(),
+ join(ns->get_ld_library_paths(), ':').c_str(),
+ join(ns->get_default_library_paths(), ':').c_str(),
+ join(ns->get_permitted_paths(), ':').c_str());
+ }
+ return false;
+ }
+ }
+
+ soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
+ if (si == nullptr) {
+ return false;
+ }
+
+ task->set_soinfo(si);
+
+ // Read the ELF header and some of the segments.
+ if (!task->read(realpath.c_str(), file_stat.st_size)) {
+ soinfo_free(si);
+ task->set_soinfo(nullptr);
+ return false;
+ }
+
+ // find and set DT_RUNPATH and dt_soname
+ // Note that these field values are temporary and are
+ // going to be overwritten on soinfo::prelink_image
+ // with values from PT_LOAD segments.
+ const ElfReader& elf_reader = task->get_elf_reader();
+ for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
+ if (d->d_tag == DT_RUNPATH) {
+ si->set_dt_runpath(elf_reader.get_string(d->d_un.d_val));
+ }
+ if (d->d_tag == DT_SONAME) {
+ si->set_soname(elf_reader.get_string(d->d_un.d_val));
+ }
+ }
+
+ for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
+ load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
+ });
+
+ return true;
+}
+
+static bool load_library(android_namespace_t* ns,
+ LoadTask* task,
+ ZipArchiveCache* zip_archive_cache,
+ LoadTaskList* load_tasks,
+ int rtld_flags,
+ bool search_linked_namespaces) {
+ const char* name = task->get_name();
+ soinfo* needed_by = task->get_needed_by();
+ const android_dlextinfo* extinfo = task->get_extinfo();
+
+ off64_t file_offset;
+ std::string realpath;
+ if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
+ file_offset = 0;
+ if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
+ file_offset = extinfo->library_fd_offset;
+ }
+
+ if (!realpath_fd(extinfo->library_fd, &realpath)) {
+ PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
+ "Will use given name.", name);
+ realpath = name;
+ }
+
+ task->set_fd(extinfo->library_fd, false);
+ task->set_file_offset(file_offset);
+ return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
+ }
+
+ // Open the file.
+ int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
+ if (fd == -1) {
+ DL_ERR("library \"%s\" not found", name);
+ return false;
+ }
+
+ task->set_fd(fd, true);
+ task->set_file_offset(file_offset);
+
+ return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
+}
+
+static bool find_loaded_library_by_soname(android_namespace_t* ns,
+ const char* name,
+ soinfo** candidate) {
+ return !ns->soinfo_list().visit([&](soinfo* si) {
+ const char* soname = si->get_soname();
+ if (soname != nullptr && (strcmp(name, soname) == 0)) {
+ *candidate = si;
+ return false;
+ }
+
+ return true;
+ });
+}
+
+// Returns true if library was found and false otherwise
+static bool find_loaded_library_by_soname(android_namespace_t* ns,
+ const char* name,
+ bool search_linked_namespaces,
+ soinfo** candidate) {
+ *candidate = nullptr;
+
+ // Ignore filename with path.
+ if (strchr(name, '/') != nullptr) {
+ return false;
+ }
+
+ bool found = find_loaded_library_by_soname(ns, name, candidate);
+
+ if (!found && search_linked_namespaces) {
+ // if a library was not found - look into linked namespaces
+ for (auto& link : ns->linked_namespaces()) {
+ if (!link.is_accessible(name)) {
+ continue;
+ }
+
+ android_namespace_t* linked_ns = link.linked_namespace();
+
+ if (find_loaded_library_by_soname(linked_ns, name, candidate)) {
+ return true;
+ }
+ }
+ }
+
+ return found;
+}
+
+static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
+ LoadTask* task) {
+ android_namespace_t* ns = namespace_link.linked_namespace();
+
+ soinfo* candidate;
+ bool loaded = false;
+
+ std::string soname;
+ if (find_loaded_library_by_soname(ns, task->get_name(), false, &candidate)) {
+ loaded = true;
+ soname = candidate->get_soname();
+ } else {
+ soname = resolve_soname(task->get_name());
+ }
+
+ if (!namespace_link.is_accessible(soname.c_str())) {
+ // the library is not accessible via namespace_link
+ return false;
+ }
+
+ // if library is already loaded - return it
+ if (loaded) {
+ task->set_soinfo(candidate);
+ return true;
+ }
+
+ // returning true with empty soinfo means that the library is okay to be
+ // loaded in the namespace buy has not yet been loaded there before.
+ task->set_soinfo(nullptr);
+ return true;
+}
+
+static bool find_library_internal(android_namespace_t* ns,
+ LoadTask* task,
+ ZipArchiveCache* zip_archive_cache,
+ LoadTaskList* load_tasks,
+ int rtld_flags,
+ bool search_linked_namespaces) {
+ soinfo* candidate;
+
+ if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) {
+ task->set_soinfo(candidate);
+ return true;
+ }
+
+ // Library might still be loaded, the accurate detection
+ // of this fact is done by load_library.
+ TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
+ task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
+
+ if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) {
+ return true;
+ }
+
+ if (search_linked_namespaces) {
+ // if a library was not found - look into linked namespaces
+ for (auto& linked_namespace : ns->linked_namespaces()) {
+ if (find_library_in_linked_namespace(linked_namespace,
+ task)) {
+ if (task->get_soinfo() == nullptr) {
+ // try to load the library - once namespace boundary is crossed
+ // we need to load a library within separate load_group
+ // to avoid using symbols from foreign namespace while.
+ //
+ // However, actual linking is deferred until when the global group
+ // is fully identified and is applied to all namespaces.
+ // Otherwise, the libs in the linked namespace won't get symbols from
+ // the global group.
+ if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
+ return true;
+ }
+ // lib was not found in the namespace. Try next linked namespace.
+ } else {
+ // lib is already loaded
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static void soinfo_unload(soinfo* si);
+static void soinfo_unload(soinfo* soinfos[], size_t count);
+
+/*
+static void shuffle(std::vector<LoadTask*>* v) {
+ for (size_t i = 0, size = v->size(); i < size; ++i) {
+ size_t n = size - i;
+ size_t r = arc4random_uniform(n);
+ std::swap((*v)[n-1], (*v)[r]);
+ }
+}
+*/
+
+// add_as_children - add first-level loaded libraries (i.e. library_names[], but
+// not their transitive dependencies) as children of the start_with library.
+// This is false when find_libraries is called for dlopen(), when newly loaded
+// libraries must form a disjoint tree.
+bool find_libraries(android_namespace_t* ns,
+ soinfo* start_with,
+ const char* const library_names[],
+ size_t library_names_count,
+ soinfo* soinfos[],
+ std::vector<soinfo*>* ld_preloads,
+ size_t ld_preloads_count,
+ int rtld_flags,
+ const android_dlextinfo* extinfo,
+ bool add_as_children,
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces) {
+ // Step 0: prepare.
+ LoadTaskList load_tasks;
+
+ for (size_t i = 0; i < library_names_count; ++i) {
+ const char* name = library_names[i];
+ load_tasks.push_back(LoadTask::create(name, start_with, ns, &readers_map));
+ }
+
+ // If soinfos array is null allocate one on stack.
+ // The array is needed in case of failure; for example
+ // when library_names[] = {libone.so, libtwo.so} and libone.so
+ // is loaded correctly but libtwo.so failed for some reason.
+ // In this case libone.so should be unloaded on return.
+ // See also implementation of failure_guard below.
+
+ if (soinfos == nullptr) {
+ size_t soinfos_size = sizeof(soinfo*)*library_names_count;
+ soinfos = reinterpret_cast<soinfo**>(alloca(soinfos_size));
+ memset(soinfos, 0, soinfos_size);
+ }
+
+ // list of libraries to link - see step 2.
+ size_t soinfos_count = 0;
+
+ auto scope_guard = android::base::make_scope_guard([&]() {
+ for (LoadTask* t : load_tasks) {
+ LoadTask::deleter(t);
+ }
+ });
+
+ auto failure_guard = android::base::make_scope_guard([&]() {
+ // Housekeeping
+ soinfo_unload(soinfos, soinfos_count);
+ });
+
+ ZipArchiveCache zip_archive_cache;
+
+ // Step 1: expand the list of load_tasks to include
+ // all DT_NEEDED libraries (do not load them just yet)
+ for (size_t i = 0; i<load_tasks.size(); ++i) {
+ LoadTask* task = load_tasks[i];
+ soinfo* needed_by = task->get_needed_by();
+
+ bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
+ task->set_extinfo(is_dt_needed ? nullptr : extinfo);
+ task->set_dt_needed(is_dt_needed);
+
+ // try to find the load.
+ // Note: start from the namespace that is stored in the LoadTask. This namespace
+ // is different from the current namespace when the LoadTask is for a transitive
+ // dependency and the lib that created the LoadTask is not found in the
+ // current namespace but in one of the linked namespace.
+ if (!find_library_internal(const_cast<android_namespace_t*>(task->get_start_from()),
+ task,
+ &zip_archive_cache,
+ &load_tasks,
+ rtld_flags,
+ search_linked_namespaces || is_dt_needed)) {
+ return false;
+ }
+
+ soinfo* si = task->get_soinfo();
+
+ if (is_dt_needed) {
+ needed_by->add_child(si);
+
+ if (si->is_linked()) {
+ si->increment_ref_count();
+ }
+ }
+
+ // When ld_preloads is not null, the first
+ // ld_preloads_count libs are in fact ld_preloads.
+ if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
+ ld_preloads->push_back(si);
+ }
+
+ if (soinfos_count < library_names_count) {
+ soinfos[soinfos_count++] = si;
+ }
+ }
+
+ // Step 2: Load libraries in random order (see b/24047022)
+ LoadTaskList load_list;
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ auto pred = [&](const LoadTask* t) {
+ return t->get_soinfo() == si;
+ };
+
+ if (!si->is_linked() &&
+ std::find_if(load_list.begin(), load_list.end(), pred) == load_list.end() ) {
+ load_list.push_back(task);
+ }
+ }
+ //shuffle(&load_list);
+
+ for (auto&& task : load_list) {
+ if (!task->load()) {
+ return false;
+ }
+ }
+
+ // Step 3: pre-link all DT_NEEDED libraries in breadth first order.
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (!si->is_linked() && !si->prelink_image()) {
+ return false;
+ }
+ }
+
+ // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
+ // determined at step 3.
+
+ // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they
+ // must be added to the global group
+ if (ld_preloads != nullptr) {
+ for (auto&& si : *ld_preloads) {
+ si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+ }
+ }
+
+ // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this
+ // run. These will be the new member of the global group
+ soinfo_list_t new_global_group_members;
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ new_global_group_members.push_back(si);
+ }
+ }
+
+ // Step 4-3: Add the new global group members to all the linked namespaces
+ for (auto si : new_global_group_members) {
+ for (auto linked_ns : *namespaces) {
+ if (si->get_primary_namespace() != linked_ns) {
+ linked_ns->add_soinfo(si);
+ si->add_secondary_namespace(linked_ns);
+ }
+ }
+ }
+
+ // Step 5: link libraries that are not destined to this namespace.
+ // Do this by recursively calling find_libraries on the namespace where the lib
+ // was found during Step 1.
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (si->get_primary_namespace() != ns) {
+ const char* name = task->get_name();
+ if (find_libraries(si->get_primary_namespace(), task->get_needed_by(), &name, 1,
+ nullptr /* soinfos */, nullptr /* ld_preloads */, 0 /* ld_preload_count */,
+ rtld_flags, nullptr /* extinfo */, false /* add_as_children */,
+ false /* search_linked_namespaces */, readers_map, namespaces)) {
+ // If this lib is directly needed by one of the libs in this namespace,
+ // then increment the count
+ soinfo* needed_by = task->get_needed_by();
+ if (needed_by != nullptr && needed_by->get_primary_namespace() == ns && si->is_linked()) {
+ si->increment_ref_count();
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // Step 6: link libraries in this namespace
+ soinfo_list_t local_group;
+ walk_dependencies_tree(
+ (start_with != nullptr && add_as_children) ? &start_with : soinfos,
+ (start_with != nullptr && add_as_children) ? 1 : soinfos_count,
+ [&] (soinfo* si) {
+ if (ns->is_accessible(si)) {
+ local_group.push_back(si);
+ return kWalkContinue;
+ } else {
+ return kWalkSkip;
+ }
+ });
+
+ soinfo_list_t global_group = ns->get_global_group();
+ bool linked = local_group.visit([&](soinfo* si) {
+ if (!si->is_linked()) {
+ if (!si->link_image(global_group, local_group, extinfo) ||
+ !get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+
+ if (linked) {
+ local_group.for_each([](soinfo* si) {
+ if (!si->is_linked()) {
+ si->set_linked();
+ }
+ });
+
+ failure_guard.Disable();
+ }
+
+ return linked;
+}
+
+static soinfo* find_library(android_namespace_t* ns,
+ const char* name, int rtld_flags,
+ const android_dlextinfo* extinfo,
+ soinfo* needed_by) {
+ soinfo* si;
+
+ // readers_map is shared across recursive calls to find_libraries.
+ // However, the map is not shared across different threads.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
+ if (name == nullptr) {
+ si = solist_get_somain();
+ } else if (!find_libraries(ns,
+ needed_by,
+ &name,
+ 1,
+ &si,
+ nullptr,
+ 0,
+ rtld_flags,
+ extinfo,
+ false /* add_as_children */,
+ true /* search_linked_namespaces */,
+ readers_map)) {
+ return nullptr;
+ }
+
+ si->increment_ref_count();
+
+ return si;
+}
+
+static void soinfo_unload(soinfo* root) {
+ if (root->is_linked()) {
+ root = root->get_local_group_root();
+ }
+
+ ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
+
+ if (!root->can_unload()) {
+ TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
+ return;
+ }
+
+ soinfo_unload(&root, 1);
+}
+
+static void soinfo_unload(soinfo* soinfos[], size_t count) {
+ // Note that the library can be loaded but not linked;
+ // in which case there is no root but we still need
+ // to walk the tree and unload soinfos involved.
+ //
+ // This happens on unsuccessful dlopen, when one of
+ // the DT_NEEDED libraries could not be linked/found.
+ if (count == 0) {
+ return;
+ }
+
+ soinfo_list_t unload_list;
+ for (size_t i = 0; i < count; ++i) {
+ soinfo* si = soinfos[i];
+
+ if (si->can_unload()) {
+ size_t ref_count = si->is_linked() ? si->decrement_ref_count() : 0;
+ if (ref_count == 0) {
+ unload_list.push_back(si);
+ } else {
+ TRACE("not unloading '%s' group, decrementing ref_count to %zd",
+ si->get_realpath(), ref_count);
+ }
+ } else {
+ TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->get_realpath());
+ return;
+ }
+ }
+
+ // This is used to identify soinfos outside of the load-group
+ // note that we cannot have > 1 in the array and have any of them
+ // linked. This is why we can safely use the first one.
+ soinfo* root = soinfos[0];
+
+ soinfo_list_t local_unload_list;
+ soinfo_list_t external_unload_list;
+ soinfo* si = nullptr;
+
+ while ((si = unload_list.pop_front()) != nullptr) {
+ if (local_unload_list.contains(si)) {
+ continue;
+ }
+
+ local_unload_list.push_back(si);
+
+ if (si->has_min_version(0)) {
+ soinfo* child = nullptr;
+ while ((child = si->get_children().pop_front()) != nullptr) {
+ TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
+ child->get_realpath(), child);
+
+ child->get_parents().remove(si);
+
+ if (local_unload_list.contains(child)) {
+ continue;
+ } else if (child->is_linked() && child->get_local_group_root() != root) {
+ external_unload_list.push_back(child);
+ } else if (child->get_parents().empty()) {
+ unload_list.push_back(child);
+ }
+ }
+ } else {
+#if !defined(__work_around_b_24465209__)
+ async_safe_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
+#else
+ PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
+ for_each_dt_needed(si, [&] (const char* library_name) {
+ TRACE("deprecated (old format of soinfo): %s needs to unload %s",
+ si->get_realpath(), library_name);
+
+ soinfo* needed = find_library(si->get_primary_namespace(),
+ library_name, RTLD_NOLOAD, nullptr, nullptr);
+
+ if (needed != nullptr) {
+ // Not found: for example if symlink was deleted between dlopen and dlclose
+ // Since we cannot really handle errors at this point - print and continue.
+ PRINT("warning: couldn't find %s needed by %s on unload.",
+ library_name, si->get_realpath());
+ return;
+ } else if (local_unload_list.contains(needed)) {
+ // already visited
+ return;
+ } else if (needed->is_linked() && needed->get_local_group_root() != root) {
+ // external group
+ external_unload_list.push_back(needed);
+ } else {
+ // local group
+ unload_list.push_front(needed);
+ }
+ });
+#endif
+ }
+ }
+
+ local_unload_list.for_each([](soinfo* si) {
+ si->call_destructors();
+ });
+
+ while ((si = local_unload_list.pop_front()) != nullptr) {
+ notify_gdb_of_unload(si);
+ get_cfi_shadow()->BeforeUnload(si);
+ soinfo_free(si);
+ }
+
+ while ((si = external_unload_list.pop_front()) != nullptr) {
+ soinfo_unload(si);
+ }
+}
+
+static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
+ if (sym_ver == nullptr) {
+ return sym_name;
+ }
+
+ return std::string(sym_name) + ", version " + sym_ver;
+}
+
+static android_namespace_t* get_caller_namespace(soinfo* caller) {
+ return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
+}
+
+void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
+ // Use basic string manipulation calls to avoid snprintf.
+ // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
+ // When debug malloc is enabled, this call returns 0. This in turn causes
+ // snprintf to do nothing, which causes libraries to fail to load.
+ // See b/17302493 for further details.
+ // Once the above bug is fixed, this code can be modified to use
+ // snprintf again.
+ const auto& default_ld_paths = g_default_namespace->get_default_library_paths();
+
+ size_t required_size = 0;
+ for (const auto& path : default_ld_paths) {
+ required_size += path.size() + 1;
+ }
+
+ if (buffer_size < required_size) {
+ async_safe_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
+ "buffer len %zu, required len %zu", buffer_size, required_size);
+ }
+
+ char* end = buffer;
+ for (size_t i = 0; i < default_ld_paths.size(); ++i) {
+ if (i > 0) *end++ = ':';
+ end = stpcpy(end, default_ld_paths[i].c_str());
+ }
+}
+
+void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
+ parse_LD_LIBRARY_PATH(ld_library_path);
+}
+
+static std::string android_dlextinfo_to_string(const android_dlextinfo* info) {
+ if (info == nullptr) {
+ return "(null)";
+ }
+
+ return stringPrintf("[flags=0x%" PRIx64 ","
+ " reserved_addr=%p,"
+ " reserved_size=0x%zx,"
+ " relro_fd=%d,"
+ " library_fd=%d,"
+ " library_fd_offset=0x%" PRIx64 ","
+ " library_namespace=%s@%p]",
+ info->flags,
+ info->reserved_addr,
+ info->reserved_size,
+ info->relro_fd,
+ info->library_fd,
+ info->library_fd_offset,
+ (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
+ (info->library_namespace != nullptr ?
+ info->library_namespace->get_name() : "(null)") : "(n/a)",
+ (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
+ info->library_namespace : nullptr);
+}
+
+void* do_dlopen(const char* name, int flags,
+ const android_dlextinfo* extinfo,
+ const void* caller_addr) {
+ std::string trace_prefix = std::string("dlopen: ") + (name == nullptr ? "(nullptr)" : name);
+ ScopedTrace trace(trace_prefix.c_str());
+ ScopedTrace loading_trace((trace_prefix + " - loading and linking").c_str());
+ soinfo* const caller = find_containing_library(caller_addr);
+ android_namespace_t* ns = get_caller_namespace(caller);
+
+ LD_LOG(kLogDlopen,
+ "dlopen(name=\"%s\", flags=0x%x, extinfo=%s, caller=\"%s\", caller_ns=%s@%p) ...",
+ name,
+ flags,
+ android_dlextinfo_to_string(extinfo).c_str(),
+ caller == nullptr ? "(null)" : caller->get_realpath(),
+ ns == nullptr ? "(null)" : ns->get_name(),
+ ns);
+
+ auto failure_guard = android::base::make_scope_guard(
+ [&]() { LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer()); });
+
+ if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
+ DL_ERR("invalid flags to dlopen: %x", flags);
+ return nullptr;
+ }
+
+ if (extinfo != nullptr) {
+ if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
+ DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);
+ return nullptr;
+ }
+
+ if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
+ (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
+ DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
+ "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
+ return nullptr;
+ }
+
+ if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
+ (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
+ DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
+ "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
+ return nullptr;
+ }
+
+ if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
+ if (extinfo->library_namespace == nullptr) {
+ DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
+ return nullptr;
+ }
+ ns = extinfo->library_namespace;
+ }
+ }
+
+ std::string asan_name_holder;
+
+ const char* translated_name = name;
+ if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
+ char original_path[PATH_MAX];
+ if (realpath(name, original_path) != nullptr) {
+ asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
+ if (file_exists(asan_name_holder.c_str())) {
+ soinfo* si = nullptr;
+ if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
+ PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
+ asan_name_holder.c_str());
+ } else {
+ PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ translated_name = asan_name_holder.c_str();
+ }
+ }
+ }
+ }
+
+ ProtectedDataGuard guard;
+ soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
+ loading_trace.End();
+
+ if (si != nullptr) {
+ void* handle = si->to_handle();
+ LD_LOG(kLogDlopen,
+ "... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p",
+ si->get_realpath(), si->get_soname(), handle);
+ si->call_constructors();
+ failure_guard.Disable();
+ LD_LOG(kLogDlopen,
+ "... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p",
+ si->get_realpath(), si->get_soname(), handle);
+ return handle;
+ }
+
+ return nullptr;
+}
+
+int do_dladdr(const void* addr, Dl_info* info) {
+ // Determine if this address can be found in any library currently mapped.
+ soinfo* si = find_containing_library(addr);
+ if (si == nullptr) {
+ return 0;
+ }
+
+ memset(info, 0, sizeof(Dl_info));
+
+ info->dli_fname = si->get_realpath();
+ // Address at which the shared object is loaded.
+ info->dli_fbase = reinterpret_cast<void*>(si->base);
+
+ // Determine if any symbol in the library contains the specified address.
+ ElfW(Sym)* sym = si->find_symbol_by_address(addr);
+ if (sym != nullptr) {
+ info->dli_sname = si->get_string(sym->st_name);
+ info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
+ }
+
+ return 1;
+}
+
+static soinfo* soinfo_from_handle(void* handle) {
+ if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
+ auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
+ if (it == g_soinfo_handles_map.end()) {
+ return nullptr;
+ } else {
+ return it->second;
+ }
+ }
+
+ return static_cast<soinfo*>(handle);
+}
+
+bool do_dlsym(void* handle,
+ const char* sym_name,
+ const char* sym_ver,
+ const void* caller_addr,
+ void** symbol) {
+ ScopedTrace trace("dlsym");
+#if !defined(__LP64__)
+ if (handle == nullptr) {
+ DL_ERR("dlsym failed: library handle is null");
+ return false;
+ }
+#endif
+
+ soinfo* found = nullptr;
+ const ElfW(Sym)* sym = nullptr;
+ soinfo* caller = find_containing_library(caller_addr);
+ android_namespace_t* ns = get_caller_namespace(caller);
+ soinfo* si = nullptr;
+ if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
+ si = soinfo_from_handle(handle);
+ }
+
+ LD_LOG(kLogDlsym,
+ "dlsym(handle=%p(\"%s\"), sym_name=\"%s\", sym_ver=\"%s\", caller=\"%s\", caller_ns=%s@%p) ...",
+ handle,
+ si != nullptr ? si->get_realpath() : "n/a",
+ sym_name,
+ sym_ver,
+ caller == nullptr ? "(null)" : caller->get_realpath(),
+ ns == nullptr ? "(null)" : ns->get_name(),
+ ns);
+
+ auto failure_guard = android::base::make_scope_guard(
+ [&]() { LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer()); });
+
+ if (sym_name == nullptr) {
+ DL_ERR("dlsym failed: symbol name is null");
+ return false;
+ }
+
+ version_info vi_instance;
+ version_info* vi = nullptr;
+
+ if (sym_ver != nullptr) {
+ vi_instance.name = sym_ver;
+ vi_instance.elf_hash = calculate_elf_hash(sym_ver);
+ vi = &vi_instance;
+ }
+
+ if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
+ sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
+ } else {
+ if (si == nullptr) {
+ DL_ERR("dlsym failed: invalid handle: %p", handle);
+ return false;
+ }
+ sym = dlsym_handle_lookup(si, &found, sym_name, vi);
+ }
+
+ if (sym != nullptr) {
+ uint32_t bind = ELF_ST_BIND(sym->st_info);
+
+ if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
+#ifdef WANT_ARM_TRACING
+ switch(ELF_ST_TYPE(sym->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ *symbol = reinterpret_cast<void*>(_create_wrapper((char*)symbol, (void*)found->resolve_symbol_address(sym), WRAPPER_DYNHOOK));
+ default:
+ *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+ }
+#else
+ *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+#endif
+ failure_guard.Disable();
+ LD_LOG(kLogDlsym,
+ "... dlsym successful: sym_name=\"%s\", sym_ver=\"%s\", found in=\"%s\", address=%p",
+ sym_name, sym_ver, found->get_soname(), *symbol);
+ return true;
+ }
+
+ DL_ERR("symbol \"%s\" found but not global", symbol_display_name(sym_name, sym_ver).c_str());
+ return false;
+ }
+
+ DL_ERR_NO_PRINT("undefined symbol: %s", symbol_display_name(sym_name, sym_ver).c_str());
+ return false;
+}
+
+int do_dlclose(void* handle) {
+ ScopedTrace trace("dlclose");
+ ProtectedDataGuard guard;
+ soinfo* si = soinfo_from_handle(handle);
+ if (si == nullptr) {
+ DL_ERR("invalid handle: %p", handle);
+ return -1;
+ }
+
+ soinfo_unload(si);
+ return 0;
+}
+
+bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) {
+ if (g_anonymous_namespace_initialized) {
+ DL_ERR("anonymous namespace has already been initialized.");
+ return false;
+ }
+
+ ProtectedDataGuard guard;
+
+ // create anonymous namespace
+ // When the caller is nullptr - create_namespace will take global group
+ // from the anonymous namespace, which is fine because anonymous namespace
+ // is still pointing to the default one.
+ android_namespace_t* anon_ns =
+ create_namespace(nullptr,
+ "(anonymous)",
+ nullptr,
+ library_search_path,
+ ANDROID_NAMESPACE_TYPE_ISOLATED,
+ nullptr,
+ g_default_namespace);
+
+ if (anon_ns == nullptr) {
+ return false;
+ }
+
+ if (!link_namespaces(anon_ns, g_default_namespace, shared_lib_sonames)) {
+ return false;
+ }
+
+ g_anonymous_namespace = anon_ns;
+ g_anonymous_namespace_initialized = true;
+
+ return true;
+}
+
+static void add_soinfos_to_namespace(const soinfo_list_t& soinfos, android_namespace_t* ns) {
+ ns->add_soinfos(soinfos);
+ for (auto si : soinfos) {
+ si->add_secondary_namespace(ns);
+ }
+}
+
+android_namespace_t* create_namespace(const void* caller_addr,
+ const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ android_namespace_t* parent_namespace) {
+ if (parent_namespace == nullptr) {
+ // if parent_namespace is nullptr -> set it to the caller namespace
+ soinfo* caller_soinfo = find_containing_library(caller_addr);
+
+ parent_namespace = caller_soinfo != nullptr ?
+ caller_soinfo->get_primary_namespace() :
+ g_anonymous_namespace;
+ }
+
+ ProtectedDataGuard guard;
+ std::vector<std::string> ld_library_paths;
+ std::vector<std::string> default_library_paths;
+ std::vector<std::string> permitted_paths;
+
+ parse_path(ld_library_path, ":", &ld_library_paths);
+ parse_path(default_library_path, ":", &default_library_paths);
+ parse_path(permitted_when_isolated_path, ":", &permitted_paths);
+
+ android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
+ ns->set_name(name);
+ ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
+ ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
+
+ if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
+ // append parent namespace paths.
+ std::copy(parent_namespace->get_ld_library_paths().begin(),
+ parent_namespace->get_ld_library_paths().end(),
+ back_inserter(ld_library_paths));
+
+ std::copy(parent_namespace->get_default_library_paths().begin(),
+ parent_namespace->get_default_library_paths().end(),
+ back_inserter(default_library_paths));
+
+ std::copy(parent_namespace->get_permitted_paths().begin(),
+ parent_namespace->get_permitted_paths().end(),
+ back_inserter(permitted_paths));
+
+ // If shared - clone the parent namespace
+ add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
+ // and copy parent namespace links
+ for (auto& link : parent_namespace->linked_namespaces()) {
+ ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames());
+ }
+ } else {
+ // If not shared - copy only the shared group
+ add_soinfos_to_namespace(parent_namespace->get_shared_group(), ns);
+ }
+
+ ns->set_ld_library_paths(std::move(ld_library_paths));
+ ns->set_default_library_paths(std::move(default_library_paths));
+ ns->set_permitted_paths(std::move(permitted_paths));
+
+ return ns;
+}
+
+bool link_namespaces(android_namespace_t* namespace_from,
+ android_namespace_t* namespace_to,
+ const char* shared_lib_sonames) {
+ if (namespace_to == nullptr) {
+ namespace_to = g_default_namespace;
+ }
+
+ if (namespace_from == nullptr) {
+ DL_ERR("error linking namespaces: namespace_from is null.");
+ return false;
+ }
+
+ if (shared_lib_sonames == nullptr || shared_lib_sonames[0] == '\0') {
+ DL_ERR("error linking namespaces \"%s\"->\"%s\": the list of shared libraries is empty.",
+ namespace_from->get_name(), namespace_to->get_name());
+ return false;
+ }
+
+ auto sonames = split(shared_lib_sonames, ":");
+ std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
+
+ ProtectedDataGuard guard;
+ namespace_from->add_linked_namespace(namespace_to, sonames_set);
+
+ return true;
+}
+
+ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
+ typedef ElfW(Addr) (*ifunc_resolver_t)(void);
+ ifunc_resolver_t ifunc_resolver = reinterpret_cast<ifunc_resolver_t>(resolver_addr);
+ ElfW(Addr) ifunc_addr = ifunc_resolver();
+ TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
+ ifunc_resolver, reinterpret_cast<void*>(ifunc_addr));
+
+ return ifunc_addr;
+}
+
+const version_info* VersionTracker::get_version_info(ElfW(Versym) source_symver) const {
+ if (source_symver < 2 ||
+ source_symver >= version_infos.size() ||
+ version_infos[source_symver].name == nullptr) {
+ return nullptr;
+ }
+
+ return &version_infos[source_symver];
+}
+
+void VersionTracker::add_version_info(size_t source_index,
+ ElfW(Word) elf_hash,
+ const char* ver_name,
+ const soinfo* target_si) {
+ if (source_index >= version_infos.size()) {
+ version_infos.resize(source_index+1);
+ }
+
+ version_infos[source_index].elf_hash = elf_hash;
+ version_infos[source_index].name = ver_name;
+ version_infos[source_index].target_si = target_si;
+}
+
+bool VersionTracker::init_verneed(const soinfo* si_from) {
+ uintptr_t verneed_ptr = si_from->get_verneed_ptr();
+
+ if (verneed_ptr == 0) {
+ return true;
+ }
+
+ size_t verneed_cnt = si_from->get_verneed_cnt();
+
+ for (size_t i = 0, offset = 0; i<verneed_cnt; ++i) {
+ const ElfW(Verneed)* verneed = reinterpret_cast<ElfW(Verneed)*>(verneed_ptr + offset);
+ size_t vernaux_offset = offset + verneed->vn_aux;
+ offset += verneed->vn_next;
+
+ if (verneed->vn_version != 1) {
+ DL_ERR("unsupported verneed[%zd] vn_version: %d (expected 1)", i, verneed->vn_version);
+ return false;
+ }
+
+ const char* target_soname = si_from->get_string(verneed->vn_file);
+ // find it in dependencies
+ soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
+ return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
+ });
+
+ if (target_si == nullptr) {
+ DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
+ target_soname, i, si_from->get_realpath());
+ return false;
+ }
+
+ for (size_t j = 0; j<verneed->vn_cnt; ++j) {
+ const ElfW(Vernaux)* vernaux = reinterpret_cast<ElfW(Vernaux)*>(verneed_ptr + vernaux_offset);
+ vernaux_offset += vernaux->vna_next;
+
+ const ElfW(Word) elf_hash = vernaux->vna_hash;
+ const char* ver_name = si_from->get_string(vernaux->vna_name);
+ ElfW(Half) source_index = vernaux->vna_other;
+
+ add_version_info(source_index, elf_hash, ver_name, target_si);
+ }
+ }
+
+ return true;
+}
+
+template <typename F>
+static bool for_each_verdef(const soinfo* si, F functor) {
+ if (!si->has_min_version(2)) {
+ return true;
+ }
+
+ uintptr_t verdef_ptr = si->get_verdef_ptr();
+ if (verdef_ptr == 0) {
+ return true;
+ }
+
+ size_t offset = 0;
+
+ size_t verdef_cnt = si->get_verdef_cnt();
+ for (size_t i = 0; i<verdef_cnt; ++i) {
+ const ElfW(Verdef)* verdef = reinterpret_cast<ElfW(Verdef)*>(verdef_ptr + offset);
+ size_t verdaux_offset = offset + verdef->vd_aux;
+ offset += verdef->vd_next;
+
+ if (verdef->vd_version != 1) {
+ DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
+ i, verdef->vd_version, si->get_realpath());
+ return false;
+ }
+
+ if ((verdef->vd_flags & VER_FLG_BASE) != 0) {
+ // "this is the version of the file itself. It must not be used for
+ // matching a symbol. It can be used to match references."
+ //
+ // http://www.akkadia.org/drepper/symbol-versioning
+ continue;
+ }
+
+ if (verdef->vd_cnt == 0) {
+ DL_ERR("invalid verdef[%zd] vd_cnt == 0 (version without a name)", i);
+ return false;
+ }
+
+ const ElfW(Verdaux)* verdaux = reinterpret_cast<ElfW(Verdaux)*>(verdef_ptr + verdaux_offset);
+
+ if (functor(i, verdef, verdaux) == true) {
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool find_verdef_version_index(const soinfo* si, const version_info* vi, ElfW(Versym)* versym) {
+ if (vi == nullptr) {
+ *versym = kVersymNotNeeded;
+ return true;
+ }
+
+ *versym = kVersymGlobal;
+
+ return for_each_verdef(si,
+ [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
+ if (verdef->vd_hash == vi->elf_hash &&
+ strcmp(vi->name, si->get_string(verdaux->vda_name)) == 0) {
+ *versym = verdef->vd_ndx;
+ return true;
+ }
+
+ return false;
+ }
+ );
+}
+
+bool VersionTracker::init_verdef(const soinfo* si_from) {
+ return for_each_verdef(si_from,
+ [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
+ add_version_info(verdef->vd_ndx, verdef->vd_hash,
+ si_from->get_string(verdaux->vda_name), si_from);
+ return false;
+ }
+ );
+}
+
+bool VersionTracker::init(const soinfo* si_from) {
+ if (!si_from->has_min_version(2)) {
+ return true;
+ }
+
+ return init_verneed(si_from) && init_verdef(si_from);
+}
+
+// TODO (dimitry): Methods below need to be moved out of soinfo
+// and in more isolated file in order minimize dependencies on
+// unnecessary object in the linker binary. Consider making them
+// independent from soinfo (?).
+bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
+ const char* sym_name, const version_info** vi) {
+ const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
+ ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
+
+ if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
+ *vi = version_tracker.get_version_info(sym_ver);
+
+ if (*vi == nullptr) {
+ DL_ERR("cannot find verneed/verdef for version index=%d "
+ "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
+ return false;
+ }
+ } else {
+ // there is no version info
+ *vi = nullptr;
+ }
+
+ return true;
+}
+
+#if !defined(__mips__)
+#if defined(USE_RELA)
+static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr) {
+ return rela->r_addend;
+}
+#else
+static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
+ if (ELFW(R_TYPE)(rel->r_info) == R_GENERIC_RELATIVE ||
+ ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE) {
+ return *reinterpret_cast<ElfW(Addr)*>(reloc_addr);
+ }
+ return 0;
+}
+#endif
+
+template<typename ElfRelIteratorT>
+bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
+ const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
+ for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
+ const auto rel = rel_iterator.next();
+ if (rel == nullptr) {
+ return false;
+ }
+
+ ElfW(Word) type = ELFW(R_TYPE)(rel->r_info);
+ ElfW(Word) sym = ELFW(R_SYM)(rel->r_info);
+
+ ElfW(Addr) reloc = static_cast<ElfW(Addr)>(rel->r_offset + load_bias);
+ ElfW(Addr) sym_addr = 0;
+ const char* sym_name = nullptr;
+ ElfW(Addr) addend = get_addend(rel, reloc);
+
+ DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
+ if (type == R_GENERIC_NONE) {
+ continue;
+ }
+
+ const ElfW(Sym)* s = nullptr;
+ soinfo* lsi = nullptr;
+
+ if (sym != 0) {
+ sym_name = get_string(symtab_[sym].st_name);
+ const version_info* vi = nullptr;
+
+ sym_addr = reinterpret_cast<ElfW(Addr)>(_get_hooked_symbol(sym_name, get_realpath()));
+ if (!sym_addr) {
+ if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
+ return false;
+ }
+
+ if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
+ return false;
+ }
+ }
+#ifdef WANT_ARM_TRACING
+ else
+ {
+ // this will be slower.
+ if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
+ return false;
+ }
+
+ if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
+ return false;
+ }
+
+ switch(ELF_ST_TYPE(s->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ sym_addr = (ElfW(Addr))_create_wrapper(sym_name, (void*)sym_addr, WRAPPER_HOOKED);
+ break;
+ }
+ }
+#endif
+
+ if (sym_addr == 0 && s == nullptr) {
+ // We only allow an undefined symbol if this is a weak reference...
+ s = &symtab_[sym];
+ if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
+ DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
+ return false;
+ }
+
+ /* IHI0044C AAELF 4.5.1.1:
+
+ Libraries are not searched to resolve weak references.
+ It is not an error for a weak reference to remain unsatisfied.
+
+ During linking, the value of an undefined weak reference is:
+ - Zero if the relocation type is absolute
+ - The address of the place if the relocation is pc-relative
+ - The address of nominal base address if the relocation
+ type is base-relative.
+ */
+
+ switch (type) {
+ case R_GENERIC_JUMP_SLOT:
+ case R_GENERIC_GLOB_DAT:
+ case R_GENERIC_RELATIVE:
+ case R_GENERIC_IRELATIVE:
+#if defined(__aarch64__)
+ case R_AARCH64_ABS64:
+ case R_AARCH64_ABS32:
+ case R_AARCH64_ABS16:
+#elif defined(__x86_64__)
+ case R_X86_64_32:
+ case R_X86_64_64:
+#elif defined(__arm__)
+ case R_ARM_ABS32:
+#elif defined(__i386__)
+ case R_386_32:
+#endif
+ /*
+ * The sym_addr was initialized to be zero above, or the relocation
+ * code below does not care about value of sym_addr.
+ * No need to do anything.
+ */
+ break;
+#if defined(__x86_64__)
+ case R_X86_64_PC32:
+ sym_addr = reloc;
+ break;
+#elif defined(__i386__)
+ case R_386_PC32:
+ sym_addr = reloc;
+ break;
+#endif
+ default:
+ DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
+ return false;
+ }
+ } else if (sym_addr == 0) { // We got a definition.
+#if !defined(__LP64__)
+ // When relocating dso with text_relocation .text segment is
+ // not executable. We need to restore elf flags before resolving
+ // STT_GNU_IFUNC symbol.
+ bool protect_segments = has_text_relocations &&
+ lsi == this &&
+ ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
+ if (protect_segments) {
+ if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+
+#ifdef WANT_ARM_TRACING
+ switch(ELF_ST_TYPE(s->st_info))
+ {
+ case STT_FUNC:
+ case STT_GNU_IFUNC:
+ case STT_ARM_TFUNC:
+ sym_addr = (ElfW(Addr))_create_wrapper(sym_name,
+ (void*)lsi->resolve_symbol_address(s), WRAPPER_UNHOOKED);
+ break;
+ default:
+ sym_addr = lsi->resolve_symbol_address(s);
+ break;
+ }
+#else
+ sym_addr = lsi->resolve_symbol_address(s);
+#endif
+
+#if !defined(__LP64__)
+ if (protect_segments) {
+ if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+ }
+ count_relocation(kRelocSymbol);
+ }
+
+ switch (type) {
+ case R_GENERIC_JUMP_SLOT:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO JMP_SLOT %16p <- %16p %s\n",
+ reinterpret_cast<void*>(reloc),
+ reinterpret_cast<void*>(sym_addr + addend), sym_name);
+
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
+ break;
+ case R_GENERIC_GLOB_DAT:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO GLOB_DAT %16p <- %16p %s\n",
+ reinterpret_cast<void*>(reloc),
+ reinterpret_cast<void*>(sym_addr + addend), sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
+ break;
+ case R_GENERIC_RELATIVE:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO RELATIVE %16p <- %16p\n",
+ reinterpret_cast<void*>(reloc),
+ reinterpret_cast<void*>(load_bias + addend));
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = (load_bias + addend);
+ break;
+ case R_GENERIC_IRELATIVE:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
+ reinterpret_cast<void*>(reloc),
+ reinterpret_cast<void*>(load_bias + addend));
+ {
+#if !defined(__LP64__)
+ // When relocating dso with text_relocation .text segment is
+ // not executable. We need to restore elf flags for this
+ // particular call.
+ if (has_text_relocations) {
+ if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+ ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
+#if !defined(__LP64__)
+ // Unprotect it afterwards...
+ if (has_text_relocations) {
+ if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
+ }
+ break;
+
+#if defined(__aarch64__)
+ case R_AARCH64_ABS64:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO ABS64 %16" PRIx64 " <- %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
+ break;
+ case R_AARCH64_ABS32:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO ABS32 %16" PRIx64 " <- %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, sym_name);
+ {
+ const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
+ const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
+ if ((min_value <= (sym_addr + addend)) &&
+ ((sym_addr + addend) <= max_value)) {
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
+ } else {
+ DL_ERR("0x%016" PRIx64 " out of range 0x%016" PRIx64 " to 0x%016" PRIx64,
+ sym_addr + addend, min_value, max_value);
+ return false;
+ }
+ }
+ break;
+ case R_AARCH64_ABS16:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO ABS16 %16" PRIx64 " <- %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, sym_name);
+ {
+ const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
+ const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
+ if ((min_value <= (sym_addr + addend)) &&
+ ((sym_addr + addend) <= max_value)) {
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
+ } else {
+ DL_ERR("0x%16" PRIx64 "out of range 0x%16" PRIx64 "to 0x%16" PRIx64,
+ sym_addr + addend, min_value, max_value);
+ return false;
+ }
+ }
+ break;
+ case R_AARCH64_PREL64:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO REL64 %16" PRIx64 " <- %16" PRIx64 " - %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, rel->r_offset, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
+ break;
+ case R_AARCH64_PREL32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO REL32 %16" PRIx64 " <- %16" PRIx64 " - %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, rel->r_offset, sym_name);
+ {
+ const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
+ const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
+ if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
+ ((sym_addr + addend - rel->r_offset) <= max_value)) {
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
+ } else {
+ DL_ERR("0x%016" PRIx64 " out of range 0x%016" PRIx64 " to 0x%016" PRIx64,
+ sym_addr + addend - rel->r_offset, min_value, max_value);
+ return false;
+ }
+ }
+ break;
+ case R_AARCH64_PREL16:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO REL16 %16" PRIx64 " <- %16" PRIx64 " - %16" PRIx64 " %s\n",
+ reloc, sym_addr + addend, rel->r_offset, sym_name);
+ {
+ const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
+ const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
+ if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
+ ((sym_addr + addend - rel->r_offset) <= max_value)) {
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
+ } else {
+ DL_ERR("0x%016" PRIx64 " out of range 0x%016" PRIx64 " to 0x%016" PRIx64,
+ sym_addr + addend - rel->r_offset, min_value, max_value);
+ return false;
+ }
+ }
+ break;
+
+ case R_AARCH64_COPY:
+ /*
+ * ET_EXEC is not supported so this should not happen.
+ *
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
+ *
+ * Section 4.6.11 "Dynamic relocations"
+ * R_AARCH64_COPY may only appear in executable objects where e_type is
+ * set to ET_EXEC.
+ */
+ DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
+ return false;
+ case R_AARCH64_TLS_TPREL64:
+ TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16" PRIx64 " <- %16" PRIx64 " - %16" PRIx64 "\n",
+ reloc, (sym_addr + addend), rel->r_offset);
+ break;
+ case R_AARCH64_TLS_DTPREL32:
+ TRACE_TYPE(RELO, "RELO TLS_DTPREL32 *** %16" PRIx64 " <- %16" PRIx64 " - %16" PRIx64 "\n",
+ reloc, (sym_addr + addend), rel->r_offset);
+ break;
+#elif defined(__x86_64__)
+ case R_X86_64_32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO R_X86_64_32 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
+ static_cast<size_t>(sym_addr), sym_name);
+ *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend;
+ break;
+ case R_X86_64_64:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO R_X86_64_64 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
+ static_cast<size_t>(sym_addr), sym_name);
+ *reinterpret_cast<Elf64_Addr*>(reloc) = sym_addr + addend;
+ break;
+ case R_X86_64_PC32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO R_X86_64_PC32 %08zx <- +%08zx (%08zx - %08zx) %s",
+ static_cast<size_t>(reloc), static_cast<size_t>(sym_addr - reloc),
+ static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
+ *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend - reloc;
+ break;
+#elif defined(__arm__)
+ case R_ARM_ABS32:
+ count_relocation(kRelocAbsolute);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
+ break;
+ case R_ARM_REL32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s",
+ reloc, sym_addr, rel->r_offset, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr - rel->r_offset;
+ break;
+ case R_ARM_COPY:
+ /*
+ * ET_EXEC is not supported so this should not happen.
+ *
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
+ *
+ * Section 4.6.1.10 "Dynamic relocations"
+ * R_ARM_COPY may only appear in executable objects where e_type is
+ * set to ET_EXEC.
+ */
+ DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
+ return false;
+#elif defined(__i386__)
+ case R_386_32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
+ break;
+ case R_386_PC32:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
+ reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr - reloc);
+ break;
+#endif
+ default:
+ DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx);
+ return false;
+ }
+ }
+ return true;
+}
+#endif // !defined(__mips__)
+
+// An empty list of soinfos
+static soinfo_list_t g_empty_list;
+
+bool soinfo::prelink_image() {
+ /* Extract dynamic section */
+ ElfW(Word) dynamic_flags = 0;
+ phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
+
+ /* We can't log anything until the linker is relocated */
+ bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
+ if (!relocating_linker) {
+ INFO("[ Linking \"%s\" ]", get_realpath());
+ DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
+ }
+
+ if (dynamic == nullptr) {
+ if (!relocating_linker) {
+ DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
+ }
+ return false;
+ } else {
+ if (!relocating_linker) {
+ DEBUG("dynamic = %p", dynamic);
+ }
+ }
+
+#if defined(__arm__)
+ (void) phdr_table_get_arm_exidx(phdr, phnum, load_bias,
+ &ARM_exidx, &ARM_exidx_count);
+#endif
+
+ // Extract useful information from dynamic section.
+ // Note that: "Except for the DT_NULL element at the end of the array,
+ // and the relative order of DT_NEEDED elements, entries may appear in any order."
+ //
+ // source: http://www.sco.com/developers/gabi/1998-04-29/ch5.dynamic.html
+ uint32_t needed_count = 0;
+ for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
+ DEBUG("d = %p, d[0](tag) = %p d[1](val) = %p",
+ d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
+ switch (d->d_tag) {
+ case DT_SONAME:
+ // this is parsed after we have strtab initialized (see below).
+ break;
+
+ case DT_HASH:
+ nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
+ nchain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
+ bucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8);
+ chain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8 + nbucket_ * 4);
+ break;
+
+ case DT_GNU_HASH:
+ gnu_nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
+ // skip symndx
+ gnu_maskwords_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[2];
+ gnu_shift2_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[3];
+
+ gnu_bloom_filter_ = reinterpret_cast<ElfW(Addr)*>(load_bias + d->d_un.d_ptr + 16);
+ gnu_bucket_ = reinterpret_cast<uint32_t*>(gnu_bloom_filter_ + gnu_maskwords_);
+ // amend chain for symndx = header[1]
+ gnu_chain_ = gnu_bucket_ + gnu_nbucket_ -
+ reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
+
+ if (!powerof2(gnu_maskwords_)) {
+ DL_ERR("invalid maskwords for gnu_hash = 0x%x, in \"%s\" expecting power to two",
+ gnu_maskwords_, get_realpath());
+ return false;
+ }
+ --gnu_maskwords_;
+
+ flags_ |= FLAG_GNU_HASH;
+ break;
+
+ case DT_STRTAB:
+ strtab_ = reinterpret_cast<const char*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_STRSZ:
+ strtab_size_ = d->d_un.d_val;
+ break;
+
+ case DT_SYMTAB:
+ symtab_ = reinterpret_cast<ElfW(Sym)*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_SYMENT:
+ if (d->d_un.d_val != sizeof(ElfW(Sym))) {
+ DL_ERR("invalid DT_SYMENT: %zd in \"%s\"",
+ static_cast<size_t>(d->d_un.d_val), get_realpath());
+ return false;
+ }
+ break;
+
+ case DT_PLTREL:
+#if defined(USE_RELA)
+ if (d->d_un.d_val != DT_RELA) {
+ DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_RELA", get_realpath());
+ return false;
+ }
+#else
+ if (d->d_un.d_val != DT_REL) {
+ DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_REL", get_realpath());
+ return false;
+ }
+#endif
+ break;
+
+ case DT_JMPREL:
+#if defined(USE_RELA)
+ plt_rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
+#else
+ plt_rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
+#endif
+ break;
+
+ case DT_PLTRELSZ:
+#if defined(USE_RELA)
+ plt_rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
+#else
+ plt_rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
+#endif
+ break;
+
+ case DT_PLTGOT:
+#if defined(__mips__)
+ // Used by mips and mips64.
+ plt_got_ = reinterpret_cast<ElfW(Addr)**>(load_bias + d->d_un.d_ptr);
+#endif
+ // Ignore for other platforms... (because RTLD_LAZY is not supported)
+ break;
+
+ case DT_DEBUG:
+ // Set the DT_DEBUG entry to the address of _r_debug for GDB
+ // if the dynamic table is writable
+// FIXME: not working currently for N64
+// The flags for the LOAD and DYNAMIC program headers do not agree.
+// The LOAD section containing the dynamic table has been mapped as
+// read-only, but the DYNAMIC header claims it is writable.
+#if !(defined(__mips__) && defined(__LP64__))
+ if ((dynamic_flags & PF_W) != 0) {
+ d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
+ }
+#endif
+ break;
+#if defined(USE_RELA)
+ case DT_RELA:
+ rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_RELASZ:
+ rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
+ break;
+
+ case DT_ANDROID_RELA:
+ android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_ANDROID_RELASZ:
+ android_relocs_size_ = d->d_un.d_val;
+ break;
+
+ case DT_ANDROID_REL:
+ DL_ERR("unsupported DT_ANDROID_REL in \"%s\"", get_realpath());
+ return false;
+
+ case DT_ANDROID_RELSZ:
+ DL_ERR("unsupported DT_ANDROID_RELSZ in \"%s\"", get_realpath());
+ return false;
+
+ case DT_RELAENT:
+ if (d->d_un.d_val != sizeof(ElfW(Rela))) {
+ DL_ERR("invalid DT_RELAENT: %zd", static_cast<size_t>(d->d_un.d_val));
+ return false;
+ }
+ break;
+
+ // ignored (see DT_RELCOUNT comments for details)
+ case DT_RELACOUNT:
+ break;
+
+ case DT_REL:
+ DL_ERR("unsupported DT_REL in \"%s\"", get_realpath());
+ return false;
+
+ case DT_RELSZ:
+ DL_ERR("unsupported DT_RELSZ in \"%s\"", get_realpath());
+ return false;
+
+#else
+ case DT_REL:
+ rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_RELSZ:
+ rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
+ break;
+
+ case DT_RELENT:
+ if (d->d_un.d_val != sizeof(ElfW(Rel))) {
+ DL_ERR("invalid DT_RELENT: %zd", static_cast<size_t>(d->d_un.d_val));
+ return false;
+ }
+ break;
+
+ case DT_ANDROID_REL:
+ android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_ANDROID_RELSZ:
+ android_relocs_size_ = d->d_un.d_val;
+ break;
+
+ case DT_ANDROID_RELA:
+ DL_ERR("unsupported DT_ANDROID_RELA in \"%s\"", get_realpath());
+ return false;
+
+ case DT_ANDROID_RELASZ:
+ DL_ERR("unsupported DT_ANDROID_RELASZ in \"%s\"", get_realpath());
+ return false;
+
+ // "Indicates that all RELATIVE relocations have been concatenated together,
+ // and specifies the RELATIVE relocation count."
+ //
+ // TODO: Spec also mentions that this can be used to optimize relocation process;
+ // Not currently used by bionic linker - ignored.
+ case DT_RELCOUNT:
+ break;
+
+ case DT_RELA:
+ DL_ERR("unsupported DT_RELA in \"%s\"", get_realpath());
+ return false;
+
+ case DT_RELASZ:
+ DL_ERR("unsupported DT_RELASZ in \"%s\"", get_realpath());
+ return false;
+
+#endif
+ case DT_INIT:
+ init_func_ = reinterpret_cast<linker_ctor_function_t>(load_bias + d->d_un.d_ptr);
+ DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
+ break;
+
+ case DT_FINI:
+ fini_func_ = reinterpret_cast<linker_dtor_function_t>(load_bias + d->d_un.d_ptr);
+ DEBUG("%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
+ break;
+
+ case DT_INIT_ARRAY:
+ init_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
+ DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
+ break;
+
+ case DT_INIT_ARRAYSZ:
+ init_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
+ break;
+
+ case DT_FINI_ARRAY:
+ fini_array_ = reinterpret_cast<linker_dtor_function_t*>(load_bias + d->d_un.d_ptr);
+ DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
+ break;
+
+ case DT_FINI_ARRAYSZ:
+ fini_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
+ break;
+
+ case DT_PREINIT_ARRAY:
+ preinit_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
+ DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
+ break;
+
+ case DT_PREINIT_ARRAYSZ:
+ preinit_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
+ break;
+
+ case DT_TEXTREL:
+#if defined(__LP64__)
+ DL_ERR("\"%s\" has text relocations", get_realpath());
+ return false;
+#else
+ has_text_relocations = true;
+ break;
+#endif
+
+ case DT_SYMBOLIC:
+ has_DT_SYMBOLIC = true;
+ break;
+
+ case DT_NEEDED:
+ ++needed_count;
+ break;
+
+ case DT_FLAGS:
+ if (d->d_un.d_val & DF_TEXTREL) {
+#if defined(__LP64__)
+ DL_ERR("\"%s\" has text relocations", get_realpath());
+ return false;
+#else
+ has_text_relocations = true;
+#endif
+ }
+ if (d->d_un.d_val & DF_SYMBOLIC) {
+ has_DT_SYMBOLIC = true;
+ }
+ break;
+
+ case DT_FLAGS_1:
+ set_dt_flags_1(d->d_un.d_val);
+
+ if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
+ DL_WARN("\"%s\" has unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
+ }
+ break;
+#if defined(__mips__)
+ case DT_MIPS_RLD_MAP:
+ // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
+ {
+ r_debug** dp = reinterpret_cast<r_debug**>(load_bias + d->d_un.d_ptr);
+ *dp = &_r_debug;
+ }
+ break;
+ case DT_MIPS_RLD_MAP_REL:
+ // Set the DT_MIPS_RLD_MAP_REL entry to the address of _r_debug for GDB.
+ {
+ r_debug** dp = reinterpret_cast<r_debug**>(
+ reinterpret_cast<ElfW(Addr)>(d) + d->d_un.d_val);
+ *dp = &_r_debug;
+ }
+ break;
+
+ case DT_MIPS_RLD_VERSION:
+ case DT_MIPS_FLAGS:
+ case DT_MIPS_BASE_ADDRESS:
+ case DT_MIPS_UNREFEXTNO:
+ break;
+
+ case DT_MIPS_SYMTABNO:
+ mips_symtabno_ = d->d_un.d_val;
+ break;
+
+ case DT_MIPS_LOCAL_GOTNO:
+ mips_local_gotno_ = d->d_un.d_val;
+ break;
+
+ case DT_MIPS_GOTSYM:
+ mips_gotsym_ = d->d_un.d_val;
+ break;
+#endif
+ // Ignored: "Its use has been superseded by the DF_BIND_NOW flag"
+ case DT_BIND_NOW:
+ break;
+
+ case DT_VERSYM:
+ versym_ = reinterpret_cast<ElfW(Versym)*>(load_bias + d->d_un.d_ptr);
+ break;
+
+ case DT_VERDEF:
+ verdef_ptr_ = load_bias + d->d_un.d_ptr;
+ break;
+ case DT_VERDEFNUM:
+ verdef_cnt_ = d->d_un.d_val;
+ break;
+
+ case DT_VERNEED:
+ verneed_ptr_ = load_bias + d->d_un.d_ptr;
+ break;
+
+ case DT_VERNEEDNUM:
+ verneed_cnt_ = d->d_un.d_val;
+ break;
+
+ case DT_RUNPATH:
+ // this is parsed after we have strtab initialized (see below).
+ break;
+
+ default:
+ if (!relocating_linker) {
+ DL_WARN("\"%s\" unused DT entry: type %p arg %p", get_realpath(),
+ reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
+ }
+ break;
+ }
+ }
+
+#if defined(__mips__) && !defined(__LP64__)
+ if (!mips_check_and_adjust_fp_modes()) {
+ return false;
+ }
+#endif
+
+ DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
+ reinterpret_cast<void*>(base), strtab_, symtab_);
+
+ // Sanity checks.
+ if (relocating_linker && needed_count != 0) {
+ DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
+ return false;
+ }
+ if (nbucket_ == 0 && gnu_nbucket_ == 0) {
+ DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
+ "(new hash type from the future?)", get_realpath());
+ return false;
+ }
+ if (strtab_ == 0) {
+ DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
+ return false;
+ }
+ if (symtab_ == 0) {
+ DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
+ return false;
+ }
+
+ // second pass - parse entries relying on strtab
+ for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
+ switch (d->d_tag) {
+ case DT_SONAME:
+ set_soname(get_string(d->d_un.d_val));
+ break;
+ case DT_RUNPATH:
+ set_dt_runpath(get_string(d->d_un.d_val));
+ break;
+ }
+ }
+
+ // Before M release linker was using basename in place of soname.
+ // In the case when dt_soname is absent some apps stop working
+ // because they can't find dt_needed library by soname.
+ // This workaround should keep them working. (applies only
+ // for apps targeting sdk version < M). Make an exception for
+ // the main executable and linker; they do not need to have dt_soname
+ if (soname_ == nullptr &&
+ this != solist_get_somain() &&
+ (flags_ & FLAG_LINKER) == 0 &&
+ get_application_target_sdk_version() < __ANDROID_API_M__) {
+ soname_ = basename(realpath_.c_str());
+ DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
+ get_realpath(), soname_);
+ // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
+ }
+ return true;
+}
+
+bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
+ const android_dlextinfo* extinfo) {
+
+ local_group_root_ = local_group.front();
+ if (local_group_root_ == nullptr) {
+ local_group_root_ = this;
+ }
+
+ if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
+ target_sdk_version_ = get_application_target_sdk_version();
+ }
+
+ VersionTracker version_tracker;
+
+ if (!version_tracker.init(this)) {
+ return false;
+ }
+
+#if !defined(__LP64__)
+ if (has_text_relocations) {
+ // Fail if app is targeting M or above.
+ if (get_application_target_sdk_version() >= __ANDROID_API_M__) {
+ DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/"
+ "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-"
+ "Enforced-for-API-level-23)", get_realpath());
+ return false;
+ }
+ // Make segments writable to allow text relocations to work properly. We will later call
+ // phdr_table_protect_segments() after all of them are applied.
+ DL_WARN("\"%s\" has text relocations (https://android.googlesource.com/platform/"
+ "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-Enforced-"
+ "for-API-level-23)", get_realpath());
+ add_dlwarning(get_realpath(), "text relocations");
+ if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+
+ if (android_relocs_ != nullptr) {
+ // check signature
+ if (android_relocs_size_ > 3 &&
+ android_relocs_[0] == 'A' &&
+ android_relocs_[1] == 'P' &&
+ android_relocs_[2] == 'S' &&
+ android_relocs_[3] == '2') {
+ DEBUG("[ android relocating %s ]", get_realpath());
+
+ bool relocated = false;
+ const uint8_t* packed_relocs = android_relocs_ + 4;
+ const size_t packed_relocs_size = android_relocs_size_ - 4;
+
+ relocated = relocate(
+ version_tracker,
+ packed_reloc_iterator<sleb128_decoder>(
+ sleb128_decoder(packed_relocs, packed_relocs_size)),
+ global_group, local_group);
+
+ if (!relocated) {
+ return false;
+ }
+ } else {
+ DL_ERR("bad android relocation header.");
+ return false;
+ }
+ }
+
+#if defined(USE_RELA)
+ if (rela_ != nullptr) {
+ DEBUG("[ relocating %s ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
+ return false;
+ }
+ }
+ if (plt_rela_ != nullptr) {
+ DEBUG("[ relocating %s plt ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
+ return false;
+ }
+ }
+#else
+ if (rel_ != nullptr) {
+ DEBUG("[ relocating %s ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
+ return false;
+ }
+ }
+ if (plt_rel_ != nullptr) {
+ DEBUG("[ relocating %s plt ]", get_realpath());
+ if (!relocate(version_tracker,
+ plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
+ return false;
+ }
+ }
+#endif
+
+#if defined(__mips__)
+ if (!mips_relocate_got(version_tracker, global_group, local_group)) {
+ return false;
+ }
+#endif
+
+ DEBUG("[ finished linking %s ]", get_realpath());
+
+#if !defined(__LP64__)
+ if (has_text_relocations) {
+ // All relocations are done, we can protect our segments back to read-only.
+ if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+#endif
+
+ // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
+ // itself --- it can't make system calls yet, and will have to call protect_relro later.
+ if (!is_linker() && !protect_relro()) {
+ return false;
+ }
+
+ /* Handle serializing/sharing the RELRO segment */
+ if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
+ if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
+ extinfo->relro_fd) < 0) {
+ DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ } else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
+ if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
+ extinfo->relro_fd) < 0) {
+ DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ }
+
+ notify_gdb_of_load(this);
+ return true;
+}
+
+bool soinfo::protect_relro() {
+ if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
+ get_realpath(), strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
+ g_default_namespace->set_isolated(false);
+ auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
+
+ char real_path[PATH_MAX];
+ std::vector<std::string> ld_default_paths;
+ for (size_t i = 0; default_ld_paths[i] != nullptr; ++i) {
+ if (realpath(default_ld_paths[i], real_path) != nullptr) {
+ ld_default_paths.push_back(real_path);
+ } else {
+ ld_default_paths.push_back(default_ld_paths[i]);
+ }
+ }
+
+ g_default_namespace->set_default_library_paths(std::move(ld_default_paths));
+
+ std::vector<android_namespace_t*> namespaces;
+ namespaces.push_back(g_default_namespace);
+ return namespaces;
+}
+
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
+ g_default_namespace->set_name("(default)");
+
+#if DISABLED_FOR_HYRBIS_SUPPORT
+ soinfo* somain = solist_get_somain();
+
+ const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
+ somain->load_bias);
+ const char* bname = basename(interp);
+
+ g_is_asan = bname != nullptr &&
+ (strcmp(bname, "linker_asan") == 0 ||
+ strcmp(bname, "linker_asan64") == 0);
+#endif
+ g_is_asan = 0;
+
+ const Config* config = nullptr;
+
+ std::string error_msg;
+
+ const char* config_file = kLdConfigFilePath;
+#ifdef USE_LD_CONFIG_FILE
+ // This is a debugging/testing only feature. Must not be available on
+ // production builds.
+ const char* ld_config_file = getenv("LD_CONFIG_FILE");
+ if (ld_config_file != nullptr && file_exists(ld_config_file)) {
+ config_file = ld_config_file;
+ }
+#endif
+
+ if (!Config::read_binary_config(config_file,
+ executable_path,
+ g_is_asan,
+ &config,
+ &error_msg)) {
+ if (!error_msg.empty()) {
+ DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
+ config_file,
+ executable_path,
+ error_msg.c_str());
+ }
+ config = nullptr;
+ }
+
+ if (config == nullptr) {
+ return init_default_namespace_no_config(g_is_asan);
+ }
+
+ const auto& namespace_configs = config->namespace_configs();
+ std::unordered_map<std::string, android_namespace_t*> namespaces;
+
+ // 1. Initialize default namespace
+ const NamespaceConfig* default_ns_config = config->default_namespace_config();
+
+ g_default_namespace->set_isolated(default_ns_config->isolated());
+ g_default_namespace->set_default_library_paths(default_ns_config->search_paths());
+ g_default_namespace->set_permitted_paths(default_ns_config->permitted_paths());
+
+ namespaces[default_ns_config->name()] = g_default_namespace;
+ if (default_ns_config->visible()) {
+ g_exported_namespaces[default_ns_config->name()] = g_default_namespace;
+ }
+
+ // 2. Initialize other namespaces
+
+ for (auto& ns_config : namespace_configs) {
+ if (namespaces.find(ns_config->name()) != namespaces.end()) {
+ continue;
+ }
+
+ android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
+ ns->set_name(ns_config->name());
+ ns->set_isolated(ns_config->isolated());
+ ns->set_default_library_paths(ns_config->search_paths());
+ ns->set_permitted_paths(ns_config->permitted_paths());
+
+ namespaces[ns_config->name()] = ns;
+ if (ns_config->visible()) {
+ g_exported_namespaces[ns_config->name()] = ns;
+ }
+ }
+
+ // 3. Establish links between namespaces
+ for (auto& ns_config : namespace_configs) {
+ auto it_from = namespaces.find(ns_config->name());
+ CHECK(it_from != namespaces.end());
+ android_namespace_t* namespace_from = it_from->second;
+ for (const NamespaceLinkConfig& ns_link : ns_config->links()) {
+ auto it_to = namespaces.find(ns_link.ns_name());
+ CHECK(it_to != namespaces.end());
+ android_namespace_t* namespace_to = it_to->second;
+ link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
+ }
+ }
+
+ // we can no longer rely on the fact that libdl.so is part of default namespace
+ // this is why we want to add ld-android.so to all namespaces from ld.config.txt
+ soinfo* ld_android_so = solist_get_head();
+ for (auto it : namespaces) {
+ it.second->add_soinfo(ld_android_so);
+ // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked
+ }
+
+ set_application_target_sdk_version(config->target_sdk_version());
+
+ std::vector<android_namespace_t*> created_namespaces;
+ created_namespaces.reserve(namespaces.size());
+ for (auto kv : namespaces) {
+ created_namespaces.push_back(kv.second);
+ }
+
+ return created_namespaces;
+}
+
+// This function finds a namespace exported in ld.config.txt by its name.
+// A namespace can be exported by setting .visible property to true.
+android_namespace_t* get_exported_namespace(const char* name) {
+ if (name == nullptr) {
+ return nullptr;
+ }
+ auto it = g_exported_namespaces.find(std::string(name));
+ if (it == g_exported_namespaces.end()) {
+ return nullptr;
+ }
+ return it->second;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker.h
^
|
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_H_
+#define _LINKER_H_
+
+#include <dlfcn.h>
+#include <android/dlext.h>
+#include <elf.h>
+#include <inttypes.h>
+#include <link.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "private/bionic_page.h"
+#include "linked_list.h"
+#include "linker_common_types.h"
+#include "linker_logger.h"
+#include "linker_soinfo.h"
+
+#include <string>
+#include <vector>
+
+#if defined(__LP64__)
+#define ELFW(what) ELF64_ ## what
+#else
+#define ELFW(what) ELF32_ ## what
+#endif
+
+// mips64 interprets Elf64_Rel structures' r_info field differently.
+// bionic (like other C libraries) has macros that assume regular ELF files,
+// but the dynamic linker needs to be able to load mips64 ELF files.
+#if defined(__mips__) && defined(__LP64__)
+#undef ELF64_R_SYM
+#undef ELF64_R_TYPE
+#undef ELF64_R_INFO
+#define ELF64_R_SYM(info) (((info) >> 0) & 0xffffffff)
+#define ELF64_R_SSYM(info) (((info) >> 32) & 0xff)
+#define ELF64_R_TYPE3(info) (((info) >> 40) & 0xff)
+#define ELF64_R_TYPE2(info) (((info) >> 48) & 0xff)
+#define ELF64_R_TYPE(info) (((info) >> 56) & 0xff)
+#endif
+
+#define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE | DF_1_PIE)
+
+// Class used construct version dependency graph.
+class VersionTracker {
+ public:
+ VersionTracker() = default;
+ bool init(const soinfo* si_from);
+
+ const version_info* get_version_info(ElfW(Versym) source_symver) const;
+ private:
+ bool init_verneed(const soinfo* si_from);
+ bool init_verdef(const soinfo* si_from);
+ void add_version_info(size_t source_index, ElfW(Word) elf_hash,
+ const char* ver_name, const soinfo* target_si);
+
+ std::vector<version_info> version_infos;
+
+ DISALLOW_COPY_AND_ASSIGN(VersionTracker);
+};
+
+bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
+ soinfo** si_found_in, const soinfo_list_t& global_group,
+ const soinfo_list_t& local_group, const ElfW(Sym)** symbol);
+
+enum RelocationKind {
+ kRelocAbsolute = 0,
+ kRelocRelative,
+ kRelocCopy,
+ kRelocSymbol,
+ kRelocMax
+};
+
+void count_relocation(RelocationKind kind);
+
+soinfo* get_libdl_info(const char* linker_path, const link_map& linker_map);
+
+soinfo* find_containing_library(const void* p);
+
+void do_android_get_LD_LIBRARY_PATH(char*, size_t);
+void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
+void* do_dlopen(const char* name,
+ int flags,
+ const android_dlextinfo* extinfo,
+ const void* caller_addr);
+
+int do_dlclose(void* handle);
+
+int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
+
+#if defined(__arm__)
+_Unwind_Ptr do_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount);
+#endif
+
+bool do_dlsym(void* handle, const char* sym_name,
+ const char* sym_ver,
+ const void* caller_addr,
+ void** symbol);
+
+int do_dladdr(const void* addr, Dl_info* info);
+
+// void ___cfi_slowpath(uint64_t CallSiteTypeId, void *Ptr, void *Ret);
+// void ___cfi_slowpath_diag(uint64_t CallSiteTypeId, void *Ptr, void *DiagData, void *Ret);
+void ___cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *Ret);
+
+void set_application_target_sdk_version(uint32_t target);
+uint32_t get_application_target_sdk_version();
+
+enum {
+ /* A regular namespace is the namespace with a custom search path that does
+ * not impose any restrictions on the location of native libraries.
+ */
+ ANDROID_NAMESPACE_TYPE_REGULAR = 0,
+
+ /* An isolated namespace requires all the libraries to be on the search path
+ * or under permitted_when_isolated_path. The search path is the union of
+ * ld_library_path and default_library_path.
+ */
+ ANDROID_NAMESPACE_TYPE_ISOLATED = 1,
+
+ /* The shared namespace clones the list of libraries of the caller namespace upon creation
+ * which means that they are shared between namespaces - the caller namespace and the new one
+ * will use the same copy of a library if it was loaded prior to android_create_namespace call.
+ *
+ * Note that libraries loaded after the namespace is created will not be shared.
+ *
+ * Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor
+ * permitted_path from the caller's namespace.
+ */
+ ANDROID_NAMESPACE_TYPE_SHARED = 2,
+
+ /* This flag instructs linker to enable grey-list workaround for the namespace.
+ * See http://b/26394120 for details.
+ */
+ ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+
+ ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
+ ANDROID_NAMESPACE_TYPE_ISOLATED,
+};
+
+bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path);
+android_namespace_t* create_namespace(const void* caller_addr,
+ const char* name,
+ const char* ld_library_path,
+ const char* default_library_path,
+ uint64_t type,
+ const char* permitted_when_isolated_path,
+ android_namespace_t* parent_namespace);
+
+bool link_namespaces(android_namespace_t* namespace_from,
+ android_namespace_t* namespace_to,
+ const char* shared_lib_sonames);
+
+android_namespace_t* get_exported_namespace(const char* name);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_allocator.cpp
^
|
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_allocator.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+#include "linker.h"
+
+#include <algorithm>
+#include <vector>
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+#include <memory.h>
+
+#include "private/bionic_prctl.h"
+
+#include "hybris_compat.h"
+
+//
+// LinkerMemeoryAllocator is general purpose allocator
+// designed to provide the same functionality as the malloc/free/realloc
+// libc functions.
+//
+// On alloc:
+// If size is >= 1k allocator proxies malloc call directly to mmap
+// If size < 1k allocator uses SmallObjectAllocator for the size
+// rounded up to the nearest power of two.
+//
+// On free:
+//
+// For a pointer allocated using proxy-to-mmap allocator unmaps
+// the memory.
+//
+// For a pointer allocated using SmallObjectAllocator it adds
+// the block to free_blocks_list_. If the number of free pages reaches 2,
+// SmallObjectAllocator munmaps one of the pages keeping the other one
+// in reserve.
+
+static const char kSignature[4] = {'L', 'M', 'A', 1};
+
+static const size_t kSmallObjectMaxSize = 1 << kSmallObjectMaxSizeLog2;
+
+// This type is used for large allocations (with size >1k)
+static const uint32_t kLargeObject = 111;
+
+bool operator<(const small_object_page_record& one, const small_object_page_record& two) {
+ return one.page_addr < two.page_addr;
+}
+
+static inline uint16_t log2(size_t number) {
+ uint16_t result = 0;
+ number--;
+
+ while (number != 0) {
+ result++;
+ number >>= 1;
+ }
+
+ return result;
+}
+
+LinkerSmallObjectAllocator::LinkerSmallObjectAllocator(uint32_t type, size_t block_size)
+ : type_(type), block_size_(block_size), free_pages_cnt_(0), free_blocks_list_(nullptr) {}
+
+void* LinkerSmallObjectAllocator::alloc() {
+ CHECK(block_size_ != 0);
+
+ if (free_blocks_list_ == nullptr) {
+ alloc_page();
+ }
+
+ small_object_block_record* block_record = free_blocks_list_;
+ if (block_record->free_blocks_cnt > 1) {
+ small_object_block_record* next_free = reinterpret_cast<small_object_block_record*>(
+ reinterpret_cast<uint8_t*>(block_record) + block_size_);
+ next_free->next = block_record->next;
+ next_free->free_blocks_cnt = block_record->free_blocks_cnt - 1;
+ free_blocks_list_ = next_free;
+ } else {
+ free_blocks_list_ = block_record->next;
+ }
+
+ // bookkeeping...
+ auto page_record = find_page_record(block_record);
+
+ if (page_record->allocated_blocks_cnt == 0) {
+ free_pages_cnt_--;
+ }
+
+ page_record->free_blocks_cnt--;
+ page_record->allocated_blocks_cnt++;
+
+ memset(block_record, 0, block_size_);
+
+ return block_record;
+}
+
+void LinkerSmallObjectAllocator::free_page(linker_vector_t::iterator page_record) {
+ void* page_start = reinterpret_cast<void*>(page_record->page_addr);
+ void* page_end = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(page_start) + PAGE_SIZE);
+
+ while (free_blocks_list_ != nullptr &&
+ free_blocks_list_ > page_start &&
+ free_blocks_list_ < page_end) {
+ free_blocks_list_ = free_blocks_list_->next;
+ }
+
+ small_object_block_record* current = free_blocks_list_;
+
+ while (current != nullptr) {
+ while (current->next > page_start && current->next < page_end) {
+ current->next = current->next->next;
+ }
+
+ current = current->next;
+ }
+
+ munmap(page_start, PAGE_SIZE);
+ page_records_.erase(page_record);
+ free_pages_cnt_--;
+}
+
+void LinkerSmallObjectAllocator::free(void* ptr) {
+ auto page_record = find_page_record(ptr);
+
+ ssize_t offset = reinterpret_cast<uintptr_t>(ptr) - sizeof(page_info);
+
+ if (offset % block_size_ != 0) {
+ async_safe_fatal("invalid pointer: %p (block_size=%zd)", ptr, block_size_);
+ }
+
+ memset(ptr, 0, block_size_);
+ small_object_block_record* block_record = reinterpret_cast<small_object_block_record*>(ptr);
+
+ block_record->next = free_blocks_list_;
+ block_record->free_blocks_cnt = 1;
+
+ free_blocks_list_ = block_record;
+
+ page_record->free_blocks_cnt++;
+ page_record->allocated_blocks_cnt--;
+
+ if (page_record->allocated_blocks_cnt == 0) {
+ if (free_pages_cnt_++ > 1) {
+ // if we already have a free page - unmap this one.
+ free_page(page_record);
+ }
+ }
+}
+
+linker_vector_t::iterator LinkerSmallObjectAllocator::find_page_record(void* ptr) {
+ void* addr = reinterpret_cast<void*>(PAGE_START(reinterpret_cast<uintptr_t>(ptr)));
+ small_object_page_record boundary;
+ boundary.page_addr = addr;
+ linker_vector_t::iterator it = std::lower_bound(
+ page_records_.begin(), page_records_.end(), boundary);
+
+ if (it == page_records_.end() || it->page_addr != addr) {
+ // not found...
+ async_safe_fatal("page record for %p was not found (block_size=%zd)", ptr, block_size_);
+ }
+
+ return it;
+}
+
+void LinkerSmallObjectAllocator::create_page_record(void* page_addr, size_t free_blocks_cnt) {
+ small_object_page_record record;
+ record.page_addr = page_addr;
+ record.free_blocks_cnt = free_blocks_cnt;
+ record.allocated_blocks_cnt = 0;
+
+ linker_vector_t::iterator it = std::lower_bound(
+ page_records_.begin(), page_records_.end(), record);
+ page_records_.insert(it, record);
+}
+
+void LinkerSmallObjectAllocator::alloc_page() {
+ static_assert(sizeof(page_info) % 16 == 0,
+ "sizeof(page_info) is not multiple of 16");
+ void* map_ptr = mmap(nullptr, PAGE_SIZE,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ if (map_ptr == MAP_FAILED) {
+ async_safe_fatal("mmap failed");
+ }
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, "linker_alloc_small_objects");
+
+ page_info* info = reinterpret_cast<page_info*>(map_ptr);
+ memcpy(info->signature, kSignature, sizeof(kSignature));
+ info->type = type_;
+ info->allocator_addr = this;
+
+ size_t free_blocks_cnt = (PAGE_SIZE - sizeof(page_info))/block_size_;
+
+ create_page_record(map_ptr, free_blocks_cnt);
+
+ small_object_block_record* first_block = reinterpret_cast<small_object_block_record*>(info + 1);
+
+ first_block->next = free_blocks_list_;
+ first_block->free_blocks_cnt = free_blocks_cnt;
+
+ free_blocks_list_ = first_block;
+}
+
+
+void LinkerMemoryAllocator::initialize_allocators() {
+ if (allocators_ != nullptr) {
+ return;
+ }
+
+ LinkerSmallObjectAllocator* allocators =
+ reinterpret_cast<LinkerSmallObjectAllocator*>(allocators_buf_);
+
+ for (size_t i = 0; i < kSmallObjectAllocatorsCount; ++i) {
+ uint32_t type = i + kSmallObjectMinSizeLog2;
+ new (allocators + i) LinkerSmallObjectAllocator(type, 1 << type);
+ }
+
+ allocators_ = allocators;
+}
+
+void* LinkerMemoryAllocator::alloc_mmap(size_t size) {
+ size_t allocated_size = PAGE_END(size + sizeof(page_info));
+ void* map_ptr = mmap(nullptr, allocated_size,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+
+ if (map_ptr == MAP_FAILED) {
+ async_safe_fatal("mmap failed");
+ }
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "linker_alloc_lob");
+
+ page_info* info = reinterpret_cast<page_info*>(map_ptr);
+ memcpy(info->signature, kSignature, sizeof(kSignature));
+ info->type = kLargeObject;
+ info->allocated_size = allocated_size;
+
+ return info + 1;
+}
+
+void* LinkerMemoryAllocator::alloc(size_t size) {
+ // treat alloc(0) as alloc(1)
+ if (size == 0) {
+ size = 1;
+ }
+
+ if (size > kSmallObjectMaxSize) {
+ return alloc_mmap(size);
+ }
+
+ uint16_t log2_size = log2(size);
+
+ if (log2_size < kSmallObjectMinSizeLog2) {
+ log2_size = kSmallObjectMinSizeLog2;
+ }
+
+ return get_small_object_allocator(log2_size)->alloc();
+}
+
+page_info* LinkerMemoryAllocator::get_page_info(void* ptr) {
+ page_info* info = reinterpret_cast<page_info*>(PAGE_START(reinterpret_cast<size_t>(ptr)));
+ if (memcmp(info->signature, kSignature, sizeof(kSignature)) != 0) {
+ async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
+ }
+
+ return info;
+}
+
+void* LinkerMemoryAllocator::realloc(void* ptr, size_t size) {
+ if (ptr == nullptr) {
+ return alloc(size);
+ }
+
+ if (size == 0) {
+ free(ptr);
+ return nullptr;
+ }
+
+ page_info* info = get_page_info(ptr);
+
+ size_t old_size = 0;
+
+ if (info->type == kLargeObject) {
+ old_size = info->allocated_size - sizeof(page_info);
+ } else {
+ LinkerSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
+ if (allocator != info->allocator_addr) {
+ async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
+ }
+
+ old_size = allocator->get_block_size();
+ }
+
+ if (old_size < size) {
+ void *result = alloc(size);
+ memcpy(result, ptr, old_size);
+ free(ptr);
+ return result;
+ }
+
+ return ptr;
+}
+
+void LinkerMemoryAllocator::free(void* ptr) {
+ if (ptr == nullptr) {
+ return;
+ }
+
+ page_info* info = get_page_info(ptr);
+
+ if (info->type == kLargeObject) {
+ munmap(info, info->allocated_size);
+ } else {
+ LinkerSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
+ if (allocator != info->allocator_addr) {
+ async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr);
+ }
+
+ allocator->free(ptr);
+ }
+}
+
+LinkerSmallObjectAllocator* LinkerMemoryAllocator::get_small_object_allocator(uint32_t type) {
+ if (type < kSmallObjectMinSizeLog2 || type > kSmallObjectMaxSizeLog2) {
+ async_safe_fatal("invalid type: %u", type);
+ }
+
+ initialize_allocators();
+ return &allocators_[type - kSmallObjectMinSizeLog2];
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_allocator.h
^
|
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_ALLOCATOR_H
+#define __LINKER_ALLOCATOR_H
+
+#include <stdlib.h>
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <vector>
+
+#include <async_safe/log.h>
+
+#include "private/bionic_prctl.h"
+
+const uint32_t kSmallObjectMaxSizeLog2 = 10;
+const uint32_t kSmallObjectMinSizeLog2 = 4;
+const uint32_t kSmallObjectAllocatorsCount = kSmallObjectMaxSizeLog2 - kSmallObjectMinSizeLog2 + 1;
+
+class LinkerSmallObjectAllocator;
+
+// This structure is placed at the beginning of each addressable page
+// and has all information we need to find the corresponding memory allocator.
+struct page_info {
+ char signature[4];
+ uint32_t type;
+ union {
+ // we use allocated_size for large objects allocator
+ size_t allocated_size;
+ // and allocator_addr for small ones.
+ LinkerSmallObjectAllocator* allocator_addr;
+ };
+} __attribute__((aligned(16)));
+
+struct small_object_page_record {
+ void* page_addr;
+ size_t free_blocks_cnt;
+ size_t allocated_blocks_cnt;
+};
+
+// for lower_bound...
+bool operator<(const small_object_page_record& one, const small_object_page_record& two);
+
+struct small_object_block_record {
+ small_object_block_record* next;
+ size_t free_blocks_cnt;
+};
+
+// This is implementation for std::vector allocator
+template <typename T>
+class linker_vector_allocator {
+ public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ T* allocate(size_t n, const T* hint = nullptr) {
+ size_t size = n * sizeof(T);
+ void* ptr = mmap(const_cast<T*>(hint), size,
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ if (ptr == MAP_FAILED) {
+ // Spec says we need to throw std::bad_alloc here but because our
+ // code does not support exception handling anyways - we are going to abort.
+ async_safe_fatal("mmap failed");
+ }
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, size, "linker_alloc_vector");
+
+ return reinterpret_cast<T*>(ptr);
+ }
+
+ void deallocate(T* ptr, size_t n) {
+ munmap(ptr, n * sizeof(T));
+ }
+};
+
+typedef
+ std::vector<small_object_page_record, linker_vector_allocator<small_object_page_record>>
+ linker_vector_t;
+
+
+class LinkerSmallObjectAllocator {
+ public:
+ LinkerSmallObjectAllocator(uint32_t type, size_t block_size);
+ void* alloc();
+ void free(void* ptr);
+
+ size_t get_block_size() const { return block_size_; }
+ private:
+ void alloc_page();
+ void free_page(linker_vector_t::iterator page_record);
+ linker_vector_t::iterator find_page_record(void* ptr);
+ void create_page_record(void* page_addr, size_t free_blocks_cnt);
+
+ uint32_t type_;
+ size_t block_size_;
+
+ size_t free_pages_cnt_;
+ small_object_block_record* free_blocks_list_;
+
+ // sorted vector of page records
+ linker_vector_t page_records_;
+};
+
+class LinkerMemoryAllocator {
+ public:
+ constexpr LinkerMemoryAllocator() : allocators_(nullptr), allocators_buf_() {}
+ void* alloc(size_t size);
+
+ // Note that this implementation of realloc never shrinks allocation
+ void* realloc(void* ptr, size_t size);
+ void free(void* ptr);
+ private:
+ void* alloc_mmap(size_t size);
+ page_info* get_page_info(void* ptr);
+ LinkerSmallObjectAllocator* get_small_object_allocator(uint32_t type);
+ void initialize_allocators();
+
+ LinkerSmallObjectAllocator* allocators_;
+ uint8_t allocators_buf_[sizeof(LinkerSmallObjectAllocator)*kSmallObjectAllocatorsCount];
+};
+
+
+#endif /* __LINKER_ALLOCATOR_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_block_allocator.cpp
^
|
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_block_allocator.h"
+#include <inttypes.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "private/bionic_prctl.h"
+
+#include "hybris_compat.h"
+
+// the multiplier should be power of 2
+static constexpr size_t round_up(size_t size, size_t multiplier) {
+ return (size + (multiplier - 1)) & ~(multiplier-1);
+}
+
+struct LinkerBlockAllocatorPage {
+ LinkerBlockAllocatorPage* next;
+ uint8_t bytes[PAGE_SIZE - 16] __attribute__((aligned(16)));
+};
+
+struct FreeBlockInfo {
+ void* next_block;
+ size_t num_free_blocks;
+};
+
+LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
+ : block_size_(
+ round_up(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size, 16)),
+ page_list_(nullptr),
+ free_block_list_(nullptr)
+{}
+
+void* LinkerBlockAllocator::alloc() {
+ if (free_block_list_ == nullptr) {
+ create_new_page();
+ }
+
+ FreeBlockInfo* block_info = reinterpret_cast<FreeBlockInfo*>(free_block_list_);
+ if (block_info->num_free_blocks > 1) {
+ FreeBlockInfo* next_block_info = reinterpret_cast<FreeBlockInfo*>(
+ reinterpret_cast<char*>(free_block_list_) + block_size_);
+ next_block_info->next_block = block_info->next_block;
+ next_block_info->num_free_blocks = block_info->num_free_blocks - 1;
+ free_block_list_ = next_block_info;
+ } else {
+ free_block_list_ = block_info->next_block;
+ }
+
+ memset(block_info, 0, block_size_);
+
+ return block_info;
+}
+
+void LinkerBlockAllocator::free(void* block) {
+ if (block == nullptr) {
+ return;
+ }
+
+ LinkerBlockAllocatorPage* page = find_page(block);
+
+ if (page == nullptr) {
+ abort();
+ }
+
+ ssize_t offset = reinterpret_cast<uint8_t*>(block) - page->bytes;
+
+ if (offset % block_size_ != 0) {
+ abort();
+ }
+
+ memset(block, 0, block_size_);
+
+ FreeBlockInfo* block_info = reinterpret_cast<FreeBlockInfo*>(block);
+
+ block_info->next_block = free_block_list_;
+ block_info->num_free_blocks = 1;
+
+ free_block_list_ = block_info;
+}
+
+void LinkerBlockAllocator::protect_all(int prot) {
+ for (LinkerBlockAllocatorPage* page = page_list_; page != nullptr; page = page->next) {
+ if (mprotect(page, PAGE_SIZE, prot) == -1) {
+ abort();
+ }
+ }
+}
+
+void LinkerBlockAllocator::create_new_page() {
+ static_assert(sizeof(LinkerBlockAllocatorPage) == PAGE_SIZE,
+ "Invalid sizeof(LinkerBlockAllocatorPage)");
+
+ LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>(
+ mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0));
+
+ if (page == MAP_FAILED) {
+ abort(); // oom
+ }
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, PAGE_SIZE, "linker_alloc");
+
+ FreeBlockInfo* first_block = reinterpret_cast<FreeBlockInfo*>(page->bytes);
+ first_block->next_block = free_block_list_;
+ first_block->num_free_blocks = (PAGE_SIZE - sizeof(LinkerBlockAllocatorPage*))/block_size_;
+
+ free_block_list_ = first_block;
+
+ page->next = page_list_;
+ page_list_ = page;
+}
+
+LinkerBlockAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
+ if (block == nullptr) {
+ abort();
+ }
+
+ LinkerBlockAllocatorPage* page = page_list_;
+ while (page != nullptr) {
+ const uint8_t* page_ptr = reinterpret_cast<const uint8_t*>(page);
+ if (block >= (page_ptr + sizeof(page->next)) && block < (page_ptr + PAGE_SIZE)) {
+ return page;
+ }
+
+ page = page->next;
+ }
+
+ abort();
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_block_allocator.h
^
|
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_BLOCK_ALLOCATOR_H
+#define __LINKER_BLOCK_ALLOCATOR_H
+
+#include <stdlib.h>
+#include <limits.h>
+#include "private/bionic_macros.h"
+
+struct LinkerBlockAllocatorPage;
+
+/*
+ * This class is a non-template version of the LinkerTypeAllocator
+ * It keeps code inside .cpp file by keeping the interface
+ * template-free.
+ *
+ * Please use LinkerTypeAllocator<type> where possible (everywhere).
+ */
+class LinkerBlockAllocator {
+ public:
+ explicit LinkerBlockAllocator(size_t block_size);
+
+ void* alloc();
+ void free(void* block);
+ void protect_all(int prot);
+
+ private:
+ void create_new_page();
+ LinkerBlockAllocatorPage* find_page(void* block);
+
+ size_t block_size_;
+ LinkerBlockAllocatorPage* page_list_;
+ void* free_block_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(LinkerBlockAllocator);
+};
+
+/*
+ * A simple allocator for the dynamic linker. An allocator allocates instances
+ * of a single fixed-size type. Allocations are backed by page-sized private
+ * anonymous mmaps.
+ *
+ * The differences between this allocator and LinkerMemoryAllocator are:
+ * 1. This allocator manages space more efficiently. LinkerMemoryAllocator
+ * operates in power-of-two sized blocks up to 1k, when this implementation
+ * splits the page to aligned size of structure; For example for structures
+ * with size 513 this allocator will use 516 (520 for lp64) bytes of data
+ * where generalized implementation is going to use 1024 sized blocks.
+ *
+ * 2. This allocator does not munmap allocated memory, where LinkerMemoryAllocator does.
+ *
+ * 3. This allocator provides mprotect services to the user, where LinkerMemoryAllocator
+ * always treats it's memory as READ|WRITE.
+ */
+template<typename T>
+class LinkerTypeAllocator {
+ public:
+ LinkerTypeAllocator() : block_allocator_(sizeof(T)) {}
+ T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); }
+ void free(T* t) { block_allocator_.free(t); }
+ void protect_all(int prot) { block_allocator_.protect_all(prot); }
+ private:
+ LinkerBlockAllocator block_allocator_;
+ DISALLOW_COPY_AND_ASSIGN(LinkerTypeAllocator);
+};
+
+#endif // __LINKER_BLOCK_ALLOCATOR_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_cfi.cpp
^
|
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_cfi.h"
+
+#include "linker_debug.h"
+#include "linker_globals.h"
+#include "linker_utils.h"
+#include "private/bionic_page.h"
+#include "private/bionic_prctl.h"
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <cstdint>
+
+// Update shadow without making it writable by preparing the data on the side and mremap-ing it in
+// place.
+class ShadowWrite {
+ char* shadow_start;
+ char* shadow_end;
+ char* aligned_start;
+ char* aligned_end;
+ char* tmp_start;
+
+ public:
+ ShadowWrite(uint16_t* s, uint16_t* e) {
+ shadow_start = reinterpret_cast<char*>(s);
+ shadow_end = reinterpret_cast<char*>(e);
+ aligned_start = reinterpret_cast<char*>(PAGE_START(reinterpret_cast<uintptr_t>(shadow_start)));
+ aligned_end = reinterpret_cast<char*>(PAGE_END(reinterpret_cast<uintptr_t>(shadow_end)));
+ tmp_start =
+ reinterpret_cast<char*>(mmap(nullptr, aligned_end - aligned_start, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
+ CHECK(tmp_start != MAP_FAILED);
+ memcpy(tmp_start, aligned_start, shadow_start - aligned_start);
+ memcpy(tmp_start + (shadow_end - aligned_start), shadow_end, aligned_end - shadow_end);
+ }
+
+ uint16_t* begin() {
+ return reinterpret_cast<uint16_t*>(tmp_start + (shadow_start - aligned_start));
+ }
+
+ uint16_t* end() {
+ return reinterpret_cast<uint16_t*>(tmp_start + (shadow_end - aligned_start));
+ }
+
+ ~ShadowWrite() {
+ size_t size = aligned_end - aligned_start;
+ mprotect(tmp_start, size, PROT_READ);
+ void* res = mremap(tmp_start, size, size, MREMAP_MAYMOVE | MREMAP_FIXED,
+ reinterpret_cast<void*>(aligned_start));
+ CHECK(res != MAP_FAILED);
+ }
+};
+
+void CFIShadowWriter::FixupVmaName() {
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *shadow_start, kShadowSize, "cfi shadow");
+}
+
+void CFIShadowWriter::AddConstant(uintptr_t begin, uintptr_t end, uint16_t v) {
+ uint16_t* shadow_begin = MemToShadow(begin);
+ uint16_t* shadow_end = MemToShadow(end - 1) + 1;
+
+ ShadowWrite sw(shadow_begin, shadow_end);
+ std::fill(sw.begin(), sw.end(), v);
+}
+
+void CFIShadowWriter::AddUnchecked(uintptr_t begin, uintptr_t end) {
+ AddConstant(begin, end, kUncheckedShadow);
+}
+
+void CFIShadowWriter::AddInvalid(uintptr_t begin, uintptr_t end) {
+ AddConstant(begin, end, kInvalidShadow);
+}
+
+void CFIShadowWriter::Add(uintptr_t begin, uintptr_t end, uintptr_t cfi_check) {
+ CHECK((cfi_check & (kCfiCheckAlign - 1)) == 0);
+
+ // Don't fill anything below cfi_check. We can not represent those addresses
+ // in the shadow, and must make sure at codegen to place all valid call
+ // targets above cfi_check.
+ begin = std::max(begin, cfi_check) & ~(kShadowAlign - 1);
+ uint16_t* shadow_begin = MemToShadow(begin);
+ uint16_t* shadow_end = MemToShadow(end - 1) + 1;
+
+ ShadowWrite sw(shadow_begin, shadow_end);
+ uint16_t sv_begin = ((begin + kShadowAlign - cfi_check) >> kCfiCheckGranularity) + kRegularShadowMin;
+
+ // With each step of the loop below, __cfi_check address computation base is increased by
+ // 2**ShadowGranularity.
+ // To compensate for that, each next shadow value must be increased by 2**ShadowGranularity /
+ // 2**CfiCheckGranularity.
+ uint16_t sv_step = 1 << (kShadowGranularity - kCfiCheckGranularity);
+ uint16_t sv = sv_begin;
+ for (uint16_t& s : sw) {
+ if (sv < sv_begin) {
+ // If shadow value wraps around, also fall back to unchecked. This means the binary is too
+ // large. FIXME: consider using a (slow) resolution function instead.
+ s = kUncheckedShadow;
+ continue;
+ }
+ // If there is something there already, fall back to unchecked. This may happen in rare cases
+ // with MAP_FIXED libraries. FIXME: consider using a (slow) resolution function instead.
+ s = (s == kInvalidShadow) ? sv : kUncheckedShadow;
+ sv += sv_step;
+ }
+}
+
+static soinfo* find_libdl(soinfo* solist) {
+ for (soinfo* si = solist; si != nullptr; si = si->next) {
+ const char* soname = si->get_soname();
+ if (soname && strcmp(soname, "libdl.so") == 0) {
+ return si;
+ }
+ }
+ return nullptr;
+}
+
+static uintptr_t soinfo_find_symbol(soinfo* si, const char* s) {
+ SymbolName name(s);
+ const ElfW(Sym) * sym;
+ if (si->find_symbol_by_name(name, nullptr, &sym) && sym) {
+ return si->resolve_symbol_address(sym);
+ }
+ return 0;
+}
+
+uintptr_t soinfo_find_cfi_check(soinfo* si) {
+ return soinfo_find_symbol(si, "__cfi_check");
+}
+
+uintptr_t CFIShadowWriter::MapShadow() {
+ void* p =
+ mmap(nullptr, kShadowSize, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ CHECK(p != MAP_FAILED);
+ return reinterpret_cast<uintptr_t>(p);
+}
+
+bool CFIShadowWriter::AddLibrary(soinfo* si) {
+ CHECK(shadow_start != nullptr);
+ if (si->base == 0 || si->size == 0) {
+ return true;
+ }
+ uintptr_t cfi_check = soinfo_find_cfi_check(si);
+ if (cfi_check == 0) {
+ INFO("[ CFI add 0x%zx + 0x%zx %s ]", static_cast<uintptr_t>(si->base),
+ static_cast<uintptr_t>(si->size), si->get_soname());
+ AddUnchecked(si->base, si->base + si->size);
+ return true;
+ }
+
+ INFO("[ CFI add 0x%zx + 0x%zx %s: 0x%zx ]", static_cast<uintptr_t>(si->base),
+ static_cast<uintptr_t>(si->size), si->get_soname(), cfi_check);
+#ifdef __arm__
+ // Require Thumb encoding.
+ if ((cfi_check & 1UL) != 1UL) {
+ DL_ERR("__cfi_check in not a Thumb function in the library \"%s\"", si->get_soname());
+ return false;
+ }
+ cfi_check &= ~1UL;
+#endif
+ if ((cfi_check & (kCfiCheckAlign - 1)) != 0) {
+ DL_ERR("unaligned __cfi_check in the library \"%s\"", si->get_soname());
+ return false;
+ }
+ Add(si->base, si->base + si->size, cfi_check);
+ return true;
+}
+
+// Pass the shadow mapping address to libdl.so. In return, we get an pointer to the location
+// libdl.so uses to store the address.
+bool CFIShadowWriter::NotifyLibDl(soinfo* solist, uintptr_t p) {
+ soinfo* libdl = find_libdl(solist);
+ if (libdl == nullptr) {
+ DL_ERR("CFI could not find libdl");
+ return false;
+ }
+
+ uintptr_t cfi_init = soinfo_find_symbol(libdl, "__cfi_init");
+ CHECK(cfi_init != 0);
+ shadow_start = reinterpret_cast<uintptr_t* (*)(uintptr_t)>(cfi_init)(p);
+ CHECK(shadow_start != nullptr);
+ CHECK(*shadow_start == p);
+ mprotect(shadow_start, PAGE_SIZE, PROT_READ);
+ return true;
+}
+
+bool CFIShadowWriter::MaybeInit(soinfo* new_si, soinfo* solist) {
+ CHECK(initial_link_done);
+ CHECK(shadow_start == nullptr);
+ // Check if CFI shadow must be initialized at this time.
+ bool found = false;
+ if (new_si == nullptr) {
+ // This is the case when we've just completed the initial link. There may have been earlier
+ // calls to MaybeInit that were skipped. Look though the entire solist.
+ for (soinfo* si = solist; si != nullptr; si = si->next) {
+ if (soinfo_find_cfi_check(si)) {
+ found = true;
+ break;
+ }
+ }
+ } else {
+ // See if the new library uses CFI.
+ found = soinfo_find_cfi_check(new_si);
+ }
+
+ // Nothing found.
+ if (!found) {
+ return true;
+ }
+
+ // Init shadow and add all currently loaded libraries (not just the new ones).
+ if (!NotifyLibDl(solist, MapShadow()))
+ return false;
+ for (soinfo* si = solist; si != nullptr; si = si->next) {
+ if (!AddLibrary(si))
+ return false;
+ }
+ FixupVmaName();
+ return true;
+}
+
+bool CFIShadowWriter::AfterLoad(soinfo* si, soinfo* solist) {
+ if (!initial_link_done) {
+ // Too early.
+ return true;
+ }
+
+ if (shadow_start == nullptr) {
+ return MaybeInit(si, solist);
+ }
+
+ // Add the new library to the CFI shadow.
+ if (!AddLibrary(si))
+ return false;
+ FixupVmaName();
+ return true;
+}
+
+void CFIShadowWriter::BeforeUnload(soinfo* si) {
+ if (shadow_start == nullptr) return;
+ if (si->base == 0 || si->size == 0) return;
+ INFO("[ CFI remove 0x%zx + 0x%zx: %s ]", static_cast<uintptr_t>(si->base),
+ static_cast<uintptr_t>(si->size), si->get_soname());
+ AddInvalid(si->base, si->base + si->size);
+ FixupVmaName();
+}
+
+bool CFIShadowWriter::InitialLinkDone(soinfo* solist) {
+ CHECK(!initial_link_done);
+ initial_link_done = true;
+ return MaybeInit(nullptr, solist);
+}
+
+// Find __cfi_check in the caller and let it handle the problem. Since caller_pc is likely not a
+// valid CFI target, we can not use CFI shadow for lookup. This does not need to be fast, do the
+// regular symbol lookup.
+void CFIShadowWriter::CfiFail(uint64_t CallSiteTypeId, void* Ptr, void* DiagData, void* CallerPc) {
+ soinfo* si = find_containing_library(CallerPc);
+ if (!si) {
+ __builtin_trap();
+ }
+
+ uintptr_t cfi_check = soinfo_find_cfi_check(si);
+ if (!cfi_check) {
+ __builtin_trap();
+ }
+
+ reinterpret_cast<CFICheckFn>(cfi_check)(CallSiteTypeId, Ptr, DiagData);
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_cfi.h
^
|
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_CFI_H_
+#define _LINKER_CFI_H_
+
+#include "linker.h"
+#include "linker_debug.h"
+
+#include <algorithm>
+
+#include "hybris_compat.h"
+#include "private/CFIShadow.h"
+
+// This class keeps the contents of CFI shadow up-to-date with the current set of loaded libraries.
+// See the comment in CFIShadow.h for more context.
+// See documentation in http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#shared-library-support.
+//
+// Shadow is mapped and initialized lazily as soon as the first CFI-enabled DSO is loaded.
+// It is updated after any library is loaded (but before any constructors are ran), and
+// before any library is unloaded.
+class CFIShadowWriter : private CFIShadow {
+ // Returns pointer to the shadow element for an address.
+ uint16_t* MemToShadow(uintptr_t x) {
+ return reinterpret_cast<uint16_t*>(*shadow_start + MemToShadowOffset(x));
+ }
+
+ // Update shadow for the address range to the given constant value.
+ void AddConstant(uintptr_t begin, uintptr_t end, uint16_t v);
+
+ // Update shadow for the address range to kUncheckedShadow.
+ void AddUnchecked(uintptr_t begin, uintptr_t end);
+
+ // Update shadow for the address range to kInvalidShadow.
+ void AddInvalid(uintptr_t begin, uintptr_t end);
+
+ // Update shadow for the address range to the given __cfi_check value.
+ void Add(uintptr_t begin, uintptr_t end, uintptr_t cfi_check);
+
+ // Add a DSO to CFI shadow.
+ bool AddLibrary(soinfo* si);
+
+ // Map CFI shadow.
+ uintptr_t MapShadow();
+
+ // Initialize CFI shadow and update its contents for everything in solist if any loaded library is
+ // CFI-enabled. If new_si != nullptr, do an incremental check by looking only at new_si; otherwise
+ // look at the entire solist.
+ bool MaybeInit(soinfo *new_si, soinfo *solist);
+
+ // Set a human readable name for the entire shadow region.
+ void FixupVmaName();
+
+ // Pass the pointer to the mapped shadow region to libdl. Must only be called once.
+ // Flips shadow_start to a non-nullptr value.
+ bool NotifyLibDl(soinfo *solist, uintptr_t p);
+
+ // Pointer to the shadow start address.
+ uintptr_t *shadow_start;
+
+ bool initial_link_done;
+
+ public:
+ // Update shadow after loading a DSO.
+ // This function will initialize the shadow if it sees a CFI-enabled DSO for the first time.
+ // In that case it will retroactively update shadow for all previously loaded DSOs. "solist" is a
+ // pointer to the global list.
+ // This function must be called before any user code has observed the newly loaded DSO.
+ bool AfterLoad(soinfo* si, soinfo *solist);
+
+ // Update shadow before unloading a DSO.
+ void BeforeUnload(soinfo* si);
+
+ // This is called as soon as the initial set of libraries is linked.
+ bool InitialLinkDone(soinfo *solist);
+
+ // Handle failure to locate __cfi_check for a target address.
+ static void CfiFail(uint64_t CallSiteTypeId, void* Ptr, void* DiagData, void *caller_pc);
+};
+
+CFIShadowWriter* get_cfi_shadow();
+
+#endif // _LINKER_CFI_H_
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_common_types.h
^
|
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_COMMON_TYPES_H
+#define __LINKER_COMMON_TYPES_H
+
+#include <android/dlext.h>
+#include "linked_list.h"
+
+// TODO(dimitry): move this to linker_defines.h? Unless it is removed by
+// consequent refactoring steps.
+
+// Android uses RELA for aarch64 and x86_64. mips64 still uses REL.
+#if defined(__aarch64__) || defined(__x86_64__)
+#define USE_RELA 1
+#endif
+
+
+struct soinfo;
+
+class SoinfoListAllocator {
+ public:
+ static LinkedListEntry<soinfo>* alloc();
+ static void free(LinkedListEntry<soinfo>* entry);
+
+ private:
+ // unconstructable
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
+};
+
+class NamespaceListAllocator {
+ public:
+ static LinkedListEntry<android_namespace_t>* alloc();
+ static void free(LinkedListEntry<android_namespace_t>* entry);
+
+ private:
+ // unconstructable
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
+};
+
+typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
+
+#endif /* __LINKER_COMMON_TYPES_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_config.cpp
^
|
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_config.h"
+
+#include "linker_globals.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+
+#include <android-base/file.h>
+#include <android-base/scopeguard.h>
+#include <android-base/strings.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include <string>
+#include <unordered_map>
+
+#include "hybris_compat.h"
+
+class ConfigParser {
+ public:
+ enum {
+ kProperty,
+ kSection,
+ kEndOfFile,
+ kError,
+ };
+
+ explicit ConfigParser(std::string&& content)
+ : content_(content), p_(0), lineno_(0), was_end_of_file_(false) {}
+
+ /*
+ * Possible return values
+ * kProperty: name is set to property name and value is set to property value
+ * kSection: name is set to section name.
+ * kEndOfFile: reached end of file.
+ * kError: error_msg is set.
+ */
+ int next_token(std::string* name, std::string* value, std::string* error_msg) {
+ std::string line;
+ while(NextLine(&line)) {
+ size_t found = line.find('#');
+ line = trim(line.substr(0, found));
+
+ if (line.empty()) {
+ continue;
+ }
+
+ if (line[0] == '[' && line[line.size() - 1] == ']') {
+ *name = line.substr(1, line.size() - 2);
+ return kSection;
+ }
+
+ found = line.find('=');
+ if (found == std::string::npos) {
+ *error_msg = std::string("invalid format: ") +
+ line +
+ ", expected \"name = property\" or \"[section]\"";
+ return kError;
+ }
+
+ *name = trim(line.substr(0, found));
+ *value = trim(line.substr(found + 1));
+ return kProperty;
+ }
+
+ // to avoid infinite cycles when programmer makes a mistake
+ CHECK(!was_end_of_file_);
+ was_end_of_file_ = true;
+ return kEndOfFile;
+ }
+
+ size_t lineno() const {
+ return lineno_;
+ }
+
+ private:
+ bool NextLine(std::string* line) {
+ if (p_ == std::string::npos) {
+ return false;
+ }
+
+ size_t found = content_.find('\n', p_);
+ if (found != std::string::npos) {
+ *line = content_.substr(p_, found - p_);
+ p_ = found + 1;
+ } else {
+ *line = content_.substr(p_);
+ p_ = std::string::npos;
+ }
+
+ lineno_++;
+ return true;
+ }
+
+ std::string content_;
+ size_t p_;
+ size_t lineno_;
+ bool was_end_of_file_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigParser);
+};
+
+class PropertyValue {
+ public:
+ PropertyValue() = default;
+
+ PropertyValue(std::string&& value, size_t lineno)
+ : value_(value), lineno_(lineno) {}
+
+ const std::string& value() const {
+ return value_;
+ }
+
+ size_t lineno() const {
+ return lineno_;
+ }
+
+ private:
+ std::string value_;
+ size_t lineno_;
+};
+
+static std::string create_error_msg(const char* file,
+ size_t lineno,
+ const std::string& msg) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s:%zu: error: %s", file, lineno, msg.c_str());
+
+ return std::string(buf);
+}
+
+static bool parse_config_file(const char* ld_config_file_path,
+ const char* binary_realpath,
+ std::unordered_map<std::string, PropertyValue>* properties,
+ std::string* error_msg) {
+ std::string content;
+ if (!readFileToString(ld_config_file_path, &content)) {
+ if (errno != ENOENT) {
+ *error_msg = std::string("error reading file \"") +
+ ld_config_file_path + "\": " + strerror(errno);
+ }
+ return false;
+ }
+
+ ConfigParser cp(std::move(content));
+
+ std::string section_name;
+
+ while(true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+ if (result == ConfigParser::kError) {
+ DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ error.c_str());
+ continue;
+ }
+
+ if (result == ConfigParser::kSection || result == ConfigParser::kEndOfFile) {
+ return false;
+ }
+
+ if (result == ConfigParser::kProperty) {
+ if (!startsWith(name, "dir.")) {
+ DL_WARN("error parsing %s:%zd: unexpected property name \"%s\", "
+ "expected format dir.<section_name> (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ name.c_str());
+ continue;
+ }
+
+ // remove trailing '/'
+ while (value[value.size() - 1] == '/') {
+ value = value.substr(0, value.size() - 1);
+ }
+
+ if (value.empty()) {
+ DL_WARN("error parsing %s:%zd: property value is empty (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno());
+ continue;
+ }
+
+ if (file_is_under_dir(binary_realpath, value)) {
+ section_name = name.substr(4);
+ break;
+ }
+ }
+ }
+
+ // skip everything until we meet a correct section
+ while (true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+
+ if (result == ConfigParser::kSection && name == section_name) {
+ break;
+ }
+
+ if (result == ConfigParser::kEndOfFile) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ cp.lineno(),
+ std::string("section \"") + section_name + "\" not found");
+ return false;
+ }
+ }
+
+ // found the section - parse it
+ while (true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+
+ if (result == ConfigParser::kEndOfFile || result == ConfigParser::kSection) {
+ break;
+ }
+
+ if (result == ConfigParser::kProperty) {
+ if (properties->find(name) != properties->end()) {
+ DL_WARN("%s:%zd: warning: property \"%s\" redefinition",
+ ld_config_file_path,
+ cp.lineno(),
+ name.c_str());
+ }
+
+ (*properties)[name] = PropertyValue(std::move(value), cp.lineno());
+ }
+
+ if (result == ConfigParser::kError) {
+ DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ error.c_str());
+ continue;
+ }
+ }
+
+ return true;
+}
+
+static Config g_config;
+
+static constexpr const char* kDefaultConfigName = "default";
+static constexpr const char* kPropertyAdditionalNamespaces = "additional.namespaces";
+#if defined(__LP64__)
+static constexpr const char* kLibParamValue = "lib64";
+#else
+static constexpr const char* kLibParamValue = "lib";
+#endif
+
+class Properties {
+ public:
+ explicit Properties(std::unordered_map<std::string, PropertyValue>&& properties)
+ : properties_(properties), target_sdk_version_(__ANDROID_API__) {}
+
+ std::vector<std::string> get_strings(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ if (it == properties_.end()) {
+ // return empty vector
+ return std::vector<std::string>();
+ }
+
+ std::vector<std::string> strings = split(it->second.value(), ",");
+
+ for (size_t i = 0; i < strings.size(); ++i) {
+ strings[i] = trim(strings[i]);
+ }
+
+ return strings;
+ }
+
+ bool get_bool(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ if (it == properties_.end()) {
+ return false;
+ }
+
+ return it->second.value() == "true";
+ }
+
+ std::string get_string(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ return (it == properties_.end()) ? "" : it->second.value();
+ }
+
+ std::vector<std::string> get_paths(const std::string& name, bool resolve, size_t* lineno = nullptr) {
+ std::string paths_str = get_string(name, lineno);
+
+ std::vector<std::string> paths;
+ split_path(paths_str.c_str(), ":", &paths);
+
+ std::vector<std::pair<std::string, std::string>> params;
+ params.push_back({ "LIB", kLibParamValue });
+ if (target_sdk_version_ != 0) {
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%d", target_sdk_version_);
+ params.push_back({ "SDK_VER", buf });
+ }
+
+ for (auto&& path : paths) {
+ format_string(&path, params);
+ }
+
+ if (resolve) {
+ std::vector<std::string> resolved_paths;
+
+ // do not remove paths that do not exist
+ resolve_paths(paths, &resolved_paths);
+
+ return resolved_paths;
+ } else {
+ return paths;
+ }
+ }
+
+ void set_target_sdk_version(int target_sdk_version) {
+ target_sdk_version_ = target_sdk_version;
+ }
+
+ private:
+ std::unordered_map<std::string, PropertyValue>::const_iterator
+ find_property(const std::string& name, size_t* lineno) const {
+ auto it = properties_.find(name);
+ if (it != properties_.end() && lineno != nullptr) {
+ *lineno = it->second.lineno();
+ }
+
+ return it;
+ }
+ std::unordered_map<std::string, PropertyValue> properties_;
+ int target_sdk_version_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Properties);
+};
+
+bool Config::read_binary_config(const char* ld_config_file_path,
+ const char* binary_realpath,
+ bool is_asan,
+ const Config** config,
+ std::string* error_msg) {
+ g_config.clear();
+
+ std::unordered_map<std::string, PropertyValue> property_map;
+ if (!parse_config_file(ld_config_file_path, binary_realpath, &property_map, error_msg)) {
+ return false;
+ }
+
+ Properties properties(std::move(property_map));
+
+ auto failure_guard = android::base::make_scope_guard([] { g_config.clear(); });
+
+ std::unordered_map<std::string, NamespaceConfig*> namespace_configs;
+
+ namespace_configs[kDefaultConfigName] = g_config.create_namespace_config(kDefaultConfigName);
+
+ std::vector<std::string> additional_namespaces = properties.get_strings(kPropertyAdditionalNamespaces);
+ for (const auto& name : additional_namespaces) {
+ namespace_configs[name] = g_config.create_namespace_config(name);
+ }
+
+ bool versioning_enabled = properties.get_bool("enable.target.sdk.version");
+ int target_sdk_version = __ANDROID_API__;
+ if (versioning_enabled) {
+ std::string version_file = dirname(binary_realpath) + "/.version";
+ std::string content;
+ if (!readFileToString(version_file, &content)) {
+ if (errno != ENOENT) {
+ *error_msg = std::string("error reading version file \"") +
+ version_file + "\": " + strerror(errno);
+ return false;
+ }
+ } else {
+ content = trim(content);
+ errno = 0;
+ char* end = nullptr;
+ const char* content_str = content.c_str();
+ int result = strtol(content_str, &end, 10);
+ if (errno == 0 && *end == '\0' && result > 0) {
+ target_sdk_version = result;
+ properties.set_target_sdk_version(target_sdk_version);
+ } else {
+ *error_msg = std::string("invalid version \"") + version_file + "\": \"" + content +"\"";
+ return false;
+ }
+ }
+ }
+
+ g_config.set_target_sdk_version(target_sdk_version);
+
+ for (auto ns_config_it : namespace_configs) {
+ auto& name = ns_config_it.first;
+ NamespaceConfig* ns_config = ns_config_it.second;
+
+ std::string property_name_prefix = std::string("namespace.") + name;
+
+ size_t lineno = 0;
+ std::vector<std::string> linked_namespaces =
+ properties.get_strings(property_name_prefix + ".links", &lineno);
+
+ for (const auto& linked_ns_name : linked_namespaces) {
+ if (namespace_configs.find(linked_ns_name) == namespace_configs.end()) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ lineno,
+ std::string("undefined namespace: ") + linked_ns_name);
+ return false;
+ }
+
+ std::string shared_libs = properties.get_string(property_name_prefix +
+ ".link." +
+ linked_ns_name +
+ ".shared_libs", &lineno);
+
+ if (shared_libs.empty()) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ lineno,
+ std::string("list of shared_libs for ") +
+ name +
+ "->" +
+ linked_ns_name +
+ " link is not specified or is empty.");
+ return false;
+ }
+
+ ns_config->add_namespace_link(linked_ns_name, shared_libs);
+ }
+
+ ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
+ ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
+
+ // these are affected by is_asan flag
+ if (is_asan) {
+ property_name_prefix += ".asan";
+ }
+
+ // search paths are resolved (canonicalized). This is required mainly for
+ // the case when /vendor is a symlink to /system/vendor, which is true for
+ // non Treble-ized legacy devices.
+ ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths", true));
+
+ // However, for permitted paths, we are not required to resolve the paths
+ // since they are only set for isolated namespaces, which implies the device
+ // is Treble-ized (= /vendor is not a symlink to /system/vendor).
+ // In fact, the resolving is causing an unexpected side effect of selinux
+ // denials on some executables which are not allowed to access some of the
+ // permitted paths.
+ ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths", false));
+ }
+
+ failure_guard.Disable();
+ *config = &g_config;
+ return true;
+}
+
+NamespaceConfig* Config::create_namespace_config(const std::string& name) {
+ namespace_configs_.push_back(std::unique_ptr<NamespaceConfig>(new NamespaceConfig(name)));
+ NamespaceConfig* ns_config_ptr = namespace_configs_.back().get();
+ namespace_configs_map_[name] = ns_config_ptr;
+ return ns_config_ptr;
+}
+
+void Config::clear() {
+ namespace_configs_.clear();
+ namespace_configs_map_.clear();
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_config.h
^
|
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_CONFIG_H_
+#define _LINKER_CONFIG_H_
+
+#include <android/api-level.h>
+
+#include <stdlib.h>
+#include <limits.h>
+#include "private/bionic_macros.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+class NamespaceLinkConfig {
+ public:
+ NamespaceLinkConfig() = default;
+ NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs)
+ : ns_name_(ns_name), shared_libs_(shared_libs) {}
+
+ const std::string& ns_name() const {
+ return ns_name_;
+ }
+
+ const std::string& shared_libs() const {
+ return shared_libs_;
+ }
+
+ private:
+ std::string ns_name_;
+ std::string shared_libs_;
+};
+
+class NamespaceConfig {
+ public:
+ explicit NamespaceConfig(const std::string& name)
+ : name_(name), isolated_(false), visible_(false)
+ {}
+
+ const char* name() const {
+ return name_.c_str();
+ }
+
+ bool isolated() const {
+ return isolated_;
+ }
+
+ bool visible() const {
+ return visible_;
+ }
+
+ const std::vector<std::string>& search_paths() const {
+ return search_paths_;
+ }
+
+ const std::vector<std::string>& permitted_paths() const {
+ return permitted_paths_;
+ }
+
+ const std::vector<NamespaceLinkConfig>& links() const {
+ return namespace_links_;
+ }
+
+ void add_namespace_link(const std::string& ns_name, const std::string& shared_libs) {
+ namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs));
+ }
+
+ void set_isolated(bool isolated) {
+ isolated_ = isolated;
+ }
+
+ void set_visible(bool visible) {
+ visible_ = visible;
+ }
+
+ void set_search_paths(std::vector<std::string>&& search_paths) {
+ search_paths_ = search_paths;
+ }
+
+ void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
+ permitted_paths_ = permitted_paths;
+ }
+ private:
+ const std::string name_;
+ bool isolated_;
+ bool visible_;
+ std::vector<std::string> search_paths_;
+ std::vector<std::string> permitted_paths_;
+ std::vector<NamespaceLinkConfig> namespace_links_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
+};
+
+class Config {
+ public:
+ Config() : target_sdk_version_(__ANDROID_API__) {}
+
+ const std::vector<std::unique_ptr<NamespaceConfig>>& namespace_configs() const {
+ return namespace_configs_;
+ }
+
+ const NamespaceConfig* default_namespace_config() const {
+ auto it = namespace_configs_map_.find("default");
+ return it == namespace_configs_map_.end() ? nullptr : it->second;
+ }
+
+ uint32_t target_sdk_version() const {
+ return target_sdk_version_;
+ }
+
+ // note that this is one time event and therefore there is no need to
+ // read every section of the config. Every linker instance needs at
+ // most one configuration.
+ // Returns false in case of an error. If binary config was not found
+ // sets *config = nullptr.
+ static bool read_binary_config(const char* ld_config_file_path,
+ const char* binary_realpath,
+ bool is_asan,
+ const Config** config,
+ std::string* error_msg);
+ private:
+ void clear();
+
+ void set_target_sdk_version(uint32_t target_sdk_version) {
+ target_sdk_version_ = target_sdk_version;
+ }
+
+ NamespaceConfig* create_namespace_config(const std::string& name);
+
+ std::vector<std::unique_ptr<NamespaceConfig>> namespace_configs_;
+ std::unordered_map<std::string, NamespaceConfig*> namespace_configs_map_;
+ uint32_t target_sdk_version_;
+
+ DISALLOW_COPY_AND_ASSIGN(Config);
+};
+
+#endif /* _LINKER_CONFIG_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_debug.h
^
|
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_DEBUG_H_
+#define _LINKER_DEBUG_H_
+
+// You can increase the verbosity of debug traces by defining the LD_DEBUG
+// environment variable to a numeric value from 0 to 2 (corresponding to
+// INFO, TRACE, and DEBUG calls in the source). This will only
+// affect new processes being launched.
+
+// By default, traces are sent to logcat, with the "linker" tag. You can
+// change this to go to stdout instead by setting the definition of
+// LINKER_DEBUG_TO_LOG to 0.
+#define LINKER_DEBUG_TO_LOG 0
+
+#define TRACE_DEBUG 1
+#define DO_TRACE_LOOKUP 1
+#define DO_TRACE_RELO 1
+#define DO_TRACE_IFUNC 1
+#define TIMING 0
+#define STATS 0
+#define COUNT_PAGES 0
+
+/*********************************************************************
+ * You shouldn't need to modify anything below unless you are adding
+ * more debugging information.
+ *
+ * To enable/disable specific debug options, change the defines above
+ *********************************************************************/
+
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+extern int g_ld_debug_verbosity;
+
+#define _PRINTVF(v, x...) \
+ do { \
+ if (g_ld_debug_verbosity > (v)) { fprintf(stderr, x); fprintf(stderr, "\n"); } \
+ } while (0)
+
+#define PRINT(x...) _PRINTVF(-1, x)
+#define INFO(x...) _PRINTVF(0, x)
+#define TRACE(x...) _PRINTVF(1, x)
+
+#if TRACE_DEBUG
+#define DEBUG(x...) _PRINTVF(2, "DEBUG: " x)
+#else /* !TRACE_DEBUG */
+#define DEBUG(x...) do {} while (0)
+#endif /* TRACE_DEBUG */
+
+#define TRACE_TYPE(t, x...) do { if (DO_TRACE_##t) { TRACE(x); } } while (0)
+
+#if COUNT_PAGES
+extern uint32_t bitmask[];
+#if defined(__LP64__)
+#define MARK(offset) \
+ do { \
+ if ((((offset) >> 12) >> 5) < 4096) \
+ bitmask[((offset) >> 12) >> 5] |= (1 << (((offset) >> 12) & 31)); \
+ } while (0)
+#else
+#define MARK(offset) \
+ do { \
+ bitmask[((offset) >> 12) >> 3] |= (1 << (((offset) >> 12) & 7)); \
+ } while (0)
+#endif
+#else
+#define MARK(x) do {} while (0)
+
+#endif
+
+#endif /* _LINKER_DEBUG_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_dlwarning.cpp
^
|
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_dlwarning.h"
+
+#include <strings.h>
+
+#include <string>
+
+#include "hybris_compat.h"
+
+static std::string current_msg;
+
+void add_dlwarning(const char* sopath, const char* message, const char* value) {
+ if (!current_msg.empty()) {
+ current_msg += '\n';
+ }
+
+ current_msg = current_msg + basename(sopath) + ": " + message;
+
+ if (value != nullptr) {
+ current_msg = current_msg + " \"" + value + "\"";
+ }
+}
+
+// Resets the current one (like dlerror but instead of
+// being thread-local it is process-local).
+void get_dlwarning(void* obj, void (*f)(void*, const char*)) {
+ if (current_msg.empty()) {
+ f(obj, nullptr);
+ } else {
+ std::string msg = current_msg;
+ current_msg.clear();
+ f(obj, msg.c_str());
+ }
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_dlwarning.h
^
|
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_DLWARNING_H
+#define __LINKER_DLWARNING_H
+
+void add_dlwarning(const char* sopath, const char* message, const char* value = nullptr);
+
+// Resets the current one (like dlerror but instead of
+// being thread-local it is process-local). The user_data
+// is used to avoid forcing user into saving the message
+// to a global variable.
+void get_dlwarning(void* user_data, void (*f)(void*, const char*));
+
+#endif /* __LINKER_DLWARNING_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_gdb_support.cpp
^
|
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_gdb_support.h"
+
+#include <pthread.h>
+
+#include "private/ScopedPthreadMutexLocker.h"
+
+#include "hybris_compat.h"
+
+// This function is an empty stub where GDB locates a breakpoint to get notified
+// about linker activity.
+extern "C"
+void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity();
+
+r_debug _r_debug =
+ {1, nullptr, reinterpret_cast<uintptr_t>(&rtld_db_dlactivity), r_debug::RT_CONSISTENT, 0};
+
+static pthread_mutex_t g__r_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
+static link_map* r_debug_head = nullptr;
+
+int _linker_enable_gdb_support = 0;
+
+void insert_link_map_into_debug_map(link_map* map) {
+ if (!_linker_enable_gdb_support) return;
+
+ // Stick the new library at the end of the list.
+ // gdb tends to care more about libc than it does
+ // about leaf libraries, and ordering it this way
+ // reduces the back-and-forth over the wire.
+
+ ///// PATCHED: we don't want libhybris modifying glibc's
+ ///// link_map objects, which should not be linked
+ ///// to bionic's stripped link_map objects.
+ ///// ==> make a copy of the whole chain
+ if(r_debug_head == nullptr && _r_debug.r_map != nullptr) {
+ link_map *glibc_link_map = new link_map(*_r_debug.r_map);
+ r_debug_head = glibc_link_map;
+
+ while(glibc_link_map->l_next != nullptr) {
+ link_map *copy_next_link_map = new link_map(*glibc_link_map->l_next);
+ glibc_link_map->l_next = copy_next_link_map;
+ copy_next_link_map->l_prev = glibc_link_map;
+
+ glibc_link_map = copy_next_link_map;
+ }
+ }
+
+ if (r_debug_head != nullptr) {
+ r_debug_head->l_prev = map;
+ map->l_next = r_debug_head;
+ map->l_prev = nullptr;
+ } else {
+ _r_debug.r_map = map;
+ map->l_prev = nullptr;
+ map->l_next = nullptr;
+ }
+ _r_debug.r_map = r_debug_head = map;
+}
+
+void remove_link_map_from_debug_map(link_map* map) {
+ if (!_linker_enable_gdb_support) return;
+
+ if (r_debug_head == map) {
+ r_debug_head = map->l_next;
+ }
+
+ if (map->l_prev) {
+ map->l_prev->l_next = map->l_next;
+ }
+ if (map->l_next) {
+ map->l_next->l_prev = map->l_prev;
+ }
+}
+
+void notify_gdb_of_load(link_map* map) {
+ ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
+
+ _r_debug.r_state = r_debug::RT_ADD;
+ rtld_db_dlactivity();
+
+ insert_link_map_into_debug_map(map);
+
+ _r_debug.r_state = r_debug::RT_CONSISTENT;
+ rtld_db_dlactivity();
+}
+
+void notify_gdb_of_unload(link_map* map) {
+ ScopedPthreadMutexLocker locker(&g__r_debug_mutex);
+
+ _r_debug.r_state = r_debug::RT_DELETE;
+ rtld_db_dlactivity();
+
+ remove_link_map_from_debug_map(map);
+
+ _r_debug.r_state = r_debug::RT_CONSISTENT;
+ rtld_db_dlactivity();
+}
+
+void notify_gdb_of_libraries() {
+ _r_debug.r_state = r_debug::RT_ADD;
+ rtld_db_dlactivity();
+ _r_debug.r_state = r_debug::RT_CONSISTENT;
+ rtld_db_dlactivity();
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_gdb_support.h
^
|
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef __LINKER_GDB_SUPPORT_H
+#define __LINKER_GDB_SUPPORT_H
+
+#include <link.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+void insert_link_map_into_debug_map(link_map* map);
+void remove_link_map_from_debug_map(link_map* map);
+void notify_gdb_of_load(link_map* map);
+void notify_gdb_of_unload(link_map* map);
+void notify_gdb_of_libraries();
+
+extern struct r_debug _r_debug;
+extern int _linker_enable_gdb_support;
+
+__END_DECLS
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_globals.cpp
^
|
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "linker_globals.h"
+#include "linker_namespaces.h"
+
+int g_argc = 0;
+char** g_argv = nullptr;
+char** g_envp = nullptr;
+
+std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
+
+static char __linker_dl_err_buf[768];
+
+char* linker_get_error_buffer() {
+ return &__linker_dl_err_buf[0];
+}
+
+size_t linker_get_error_buffer_size() {
+ return sizeof(__linker_dl_err_buf);
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_globals.h
^
|
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_GLOBALS_H
+#define __LINKER_GLOBALS_H
+
+#include <link.h>
+#include <stddef.h>
+
+#include <unordered_map>
+
+#include <async_safe/log.h>
+
+#define DL_ERR(fmt, x...) \
+ do { \
+ fprintf(stderr, fmt, ##x); \
+ fprintf(stderr, "\n"); \
+ /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
+ } while (false)
+
+#define DL_ERR_NO_PRINT(fmt, x...) \
+ do { \
+ /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
+ DEBUG("%s\n", linker_get_error_buffer()); \
+ } while (false)
+
+#define DL_WARN(fmt, x...) \
+ do { \
+ fprintf(stderr, "WARNING: linker " fmt, ##x); \
+ fprintf(stderr, "\n"); \
+ } while (false)
+
+#define DL_ERR_AND_LOG(fmt, x...) \
+ do { \
+ DL_ERR(fmt, x); \
+ PRINT(fmt, x); \
+ } while (false)
+
+constexpr ElfW(Versym) kVersymNotNeeded = 0;
+constexpr ElfW(Versym) kVersymGlobal = 1;
+
+// These values are used to call constructors for .init_array && .preinit_array
+extern int g_argc;
+extern char** g_argv;
+extern char** g_envp;
+
+struct soinfo;
+struct android_namespace_t;
+
+extern android_namespace_t *g_default_namespace;
+
+extern std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
+
+// Error buffer "variable"
+char* linker_get_error_buffer();
+size_t linker_get_error_buffer_size();
+
+extern void* (*_get_hooked_symbol)(const char *sym, const char *requester);
+
+#ifdef WANT_ARM_TRACING
+extern void *(*_create_wrapper)(const char *symbol, void *function, int wrapper_type);
+#endif
+
+#endif /* __LINKER_GLOBALS_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_libc_support.c
^
|
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "../libc/arch-common/bionic/__dso_handle.h"
+#include "../libc/arch-common/bionic/pthread_atfork.h"
+
+int atexit(void (*function)(void) __attribute__((__unused__))) {
+ return -1;
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_libcxx_support.cpp
^
|
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <async_safe/log.h>
+
+void* __find_icu_symbol(const char* symbol_name __attribute__((__unused__))) {
+ async_safe_fatal("__find_icu_symbol should not be called in the linker");
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_logger.cpp
^
|
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_logger.h"
+
+#include <string.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <async_safe/log.h>
+
+#include "linker_utils.h"
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+#include "private/CachedProperty.h"
+#endif
+
+#include "hybris_compat.h"
+
+LinkerLogger g_linker_logger;
+bool g_greylist_disabled = false;
+
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+static uint32_t ParseProperty(const std::string& value) {
+ if (value.empty()) {
+ return 0;
+ }
+
+ std::vector<std::string> options = split(value, ",");
+
+ uint32_t flags = 0;
+
+ for (const auto& o : options) {
+ if (o == "dlerror") {
+ flags |= kLogErrors;
+ } else if (o == "dlopen") {
+ flags |= kLogDlopen;
+ } else if (o == "dlsym") {
+ flags |= kLogDlsym;
+ } else {
+ async_safe_format_log(ANDROID_LOG_WARN, "linker", "Ignoring unknown debug.ld option \"%s\"",
+ o.c_str());
+ }
+ }
+
+ return flags;
+}
+#endif
+
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+static void GetAppSpecificProperty(char* buffer) {
+ // Get process basename.
+ const char* process_name_start = basename(g_argv[0]);
+
+ // Remove ':' and everything after it. This is the naming convention for
+ // services: https://developer.android.com/guide/components/services.html
+ const char* process_name_end = strchr(process_name_start, ':');
+
+ std::string process_name = (process_name_end != nullptr) ?
+ std::string(process_name_start, (process_name_end - process_name_start)) :
+ std::string(process_name_start);
+
+ std::string property_name = std::string("debug.ld.app.") + process_name;
+ __system_property_get(property_name.c_str(), buffer);
+}
+#endif
+
+void LinkerLogger::ResetState() {
+ // The most likely scenario app is not debuggable and
+ // is running on a user build, in which case logging is disabled.
+ if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) {
+ return;
+ }
+
+ // This is a convenient place to check whether the greylist should be disabled for testing.
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+ static CachedProperty greylist_disabled("debug.ld.greylist_disabled");
+ bool old_value = g_greylist_disabled;
+ g_greylist_disabled = (strcmp(greylist_disabled.Get(), "true") == 0);
+ if (g_greylist_disabled != old_value) {
+ async_safe_format_log(ANDROID_LOG_INFO, "linker", "%s greylist",
+ g_greylist_disabled ? "Disabling" : "Enabling");
+ }
+ flags_ = 0;
+
+ // For logging, check the flag applied to all processes first.
+ static CachedProperty debug_ld_all("debug.ld.all");
+ flags_ |= ParseProperty(debug_ld_all.Get());
+#endif
+ // Ignore processes started without argv (http://b/33276926).
+ if (g_argv[0] == nullptr) {
+ return;
+ }
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+ // Otherwise check the app-specific property too.
+ // We can't easily cache the property here because argv[0] changes.
+ char debug_ld_app[PROP_VALUE_MAX] = {};
+ GetAppSpecificProperty(debug_ld_app);
+ flags_ |= ParseProperty(debug_ld_app);
+#endif
+}
+
+void LinkerLogger::Log(uint32_t type, const char* format, ...) {
+ if ((flags_ & type) == 0) {
+ return;
+ }
+
+ va_list ap;
+ va_start(ap, format);
+ async_safe_format_log_va_list(ANDROID_LOG_DEBUG, "linker", format, ap);
+ va_end(ap);
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_logger.h
^
|
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_LOGGER_H_
+#define _LINKER_LOGGER_H_
+
+#include <stdlib.h>
+#include <limits.h>
+#include "private/bionic_macros.h"
+#include "private/bionic_systrace.h"
+
+#define LD_LOG(type, x...) \
+ { \
+ g_linker_logger.Log(type, x); \
+ }
+
+constexpr const uint32_t kLogErrors = 1 << 0;
+constexpr const uint32_t kLogDlopen = 1 << 1;
+constexpr const uint32_t kLogDlsym = 1 << 2;
+
+class LinkerLogger {
+ public:
+ LinkerLogger() : flags_(0) { }
+
+ void ResetState();
+ void Log(uint32_t type, const char* format, ...);
+ private:
+ uint32_t flags_;
+
+ DISALLOW_COPY_AND_ASSIGN(LinkerLogger);
+};
+
+extern LinkerLogger g_linker_logger;
+extern char** g_argv;
+
+// If the system property debug.ld.greylist_disabled is true, we'll not use the greylist
+// regardless of API level.
+extern bool g_greylist_disabled;
+
+#endif /* _LINKER_LOGGER_H_ */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_main.cpp
^
|
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hybris_compat.h"
+
+#include "linker_main.h"
+
+#include "linker_debug.h"
+#include "linker_cfi.h"
+#include "linker_gdb_support.h"
+#include "linker_globals.h"
+#include "linker_phdr.h"
+#include "linker_utils.h"
+
+#include "private/bionic_globals.h"
+#include "private/bionic_tls.h"
+#include "private/KernelArgumentBlock.h"
+
+#include "android-base/strings.h"
+#include "android-base/stringprintf.h"
+#ifdef __ANDROID__
+#include "debuggerd/handler.h"
+#endif
+
+#include <async_safe/log.h>
+
+#include <vector>
+
+extern void __libc_init_globals(KernelArgumentBlock&);
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
+#endif
+
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+extern "C" void _start();
+#endif
+
+static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
+
+// These should be preserved static to avoid emitting
+// RELATIVE relocations for the part of the code running
+// before linker links itself.
+
+// TODO (dimtiry): remove somain, rename solist to solist_head
+static soinfo* solist;
+static soinfo* sonext;
+static soinfo* somain; // main process, always the one after libdl_info
+
+void solist_add_soinfo(soinfo* si) {
+ sonext->next = si;
+ sonext = si;
+}
+
+bool solist_remove_soinfo(soinfo* si) {
+ soinfo *prev = nullptr, *trav;
+ for (trav = solist; trav != nullptr; trav = trav->next) {
+ if (trav == si) {
+ break;
+ }
+ prev = trav;
+ }
+
+ if (trav == nullptr) {
+ // si was not in solist
+ PRINT("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
+ return false;
+ }
+
+ // prev will never be null, because the first entry in solist is
+ // always the static libdl_info.
+ CHECK(prev != nullptr);
+ prev->next = si->next;
+ if (si == sonext) {
+ sonext = prev;
+ }
+
+ return true;
+}
+
+soinfo* solist_get_head() {
+ return solist;
+}
+
+soinfo* solist_get_somain() {
+ return somain;
+}
+
+int g_ld_debug_verbosity;
+abort_msg_t* g_abort_message = nullptr; // For debuggerd.
+
+static std::vector<std::string> g_ld_preload_names;
+
+static std::vector<soinfo*> g_ld_preloads;
+
+static void parse_path(const char* path, const char* delimiters,
+ std::vector<std::string>* resolved_paths) {
+ std::vector<std::string> paths;
+ split_path(path, delimiters, &paths);
+ resolve_paths(paths, resolved_paths);
+}
+
+static void parse_LD_LIBRARY_PATH(const char* path) {
+ std::vector<std::string> ld_libary_paths;
+ parse_path(path, ":", &ld_libary_paths);
+ g_default_namespace->set_ld_library_paths(std::move(ld_libary_paths));
+}
+
+static void parse_LD_PRELOAD(const char* path) {
+ g_ld_preload_names.clear();
+ if (path != nullptr) {
+ // We have historically supported ':' as well as ' ' in LD_PRELOAD.
+ g_ld_preload_names = split(path, " :");
+ std::remove_if(g_ld_preload_names.begin(),
+ g_ld_preload_names.end(),
+ [] (const std::string& s) { return s.empty(); });
+ }
+}
+
+// An empty list of soinfos
+static soinfo_list_t g_empty_list;
+
+static void add_vdso(KernelArgumentBlock& args) {
+ ElfW(Ehdr)* ehdr_vdso = reinterpret_cast<ElfW(Ehdr)*>(args.getauxval(AT_SYSINFO_EHDR));
+ if (ehdr_vdso == nullptr) {
+ return;
+ }
+
+ soinfo* si = soinfo_alloc(g_default_namespace, "[vdso]", nullptr, 0, 0);
+
+ si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
+ si->phnum = ehdr_vdso->e_phnum;
+ si->base = reinterpret_cast<ElfW(Addr)>(ehdr_vdso);
+ si->size = phdr_table_get_load_size(si->phdr, si->phnum);
+ si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
+
+ si->prelink_image();
+ si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
+}
+
+/* gdb expects the linker to be in the debug shared object list.
+ * Without this, gdb has trouble locating the linker's ".text"
+ * and ".plt" sections. Gdb could also potentially use this to
+ * relocate the offset of our exported 'rtld_db_dlactivity' symbol.
+ * Note that the linker shouldn't be on the soinfo list.
+ */
+static link_map linker_link_map;
+
+static void init_linker_info_for_gdb(ElfW(Addr) linker_base, char* linker_path) {
+ linker_link_map.l_addr = linker_base;
+ linker_link_map.l_name = linker_path;
+
+ /*
+ * Set the dynamic field in the link map otherwise gdb will complain with
+ * the following:
+ * warning: .dynamic section for "/system/bin/linker" is not at the
+ * expected address (wrong library or version mismatch?)
+ */
+ ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
+ ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
+ phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
+ &linker_link_map.l_ld, nullptr);
+
+}
+
+extern "C" int __system_properties_init(void);
+
+static const char* get_executable_path() {
+ static std::string executable_path;
+ if (executable_path.empty()) {
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+ if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
+ async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
+ }
+ executable_path = std::string(path, path_len);
+ }
+
+ return executable_path.c_str();
+}
+
+#if defined(__LP64__)
+static char kLinkerPath[] = "/system/bin/linker64";
+#else
+static char kLinkerPath[] = "/system/bin/linker";
+#endif
+
+/*
+ * This code is called after the linker has linked itself and
+ * fixed it's own GOT. It is safe to make references to externs
+ * and other non-local data at this point.
+ */
+static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
+ ProtectedDataGuard guard;
+
+#if TIMING
+ struct timeval t0, t1;
+ gettimeofday(&t0, 0);
+#endif
+
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+ // Sanitize the environment.
+ __libc_init_AT_SECURE(args);
+
+ // Initialize system properties
+ __system_properties_init(); // may use 'environ'
+
+ // Register the debuggerd signal handler.
+#ifdef __ANDROID__
+ debuggerd_callbacks_t callbacks = {
+ .get_abort_message = []() {
+ return g_abort_message;
+ },
+ .post_dump = ¬ify_gdb_of_libraries,
+ };
+ debuggerd_init(&callbacks);
+#endif
+#endif
+
+ g_linker_logger.ResetState();
+
+ // Get a few environment variables.
+ const char* LD_DEBUG = getenv("HYBRIS_LD_DEBUG");
+ if (LD_DEBUG != nullptr) {
+ g_ld_debug_verbosity = atoi(LD_DEBUG);
+ }
+
+#if defined(__LP64__)
+ INFO("[ Android dynamic linker (64-bit) ]");
+#else
+ INFO("[ Android dynamic linker (32-bit) ]");
+#endif
+
+ // These should have been sanitized by __libc_init_AT_SECURE, but the test
+ // doesn't cost us anything.
+ const char* ldpath_env = nullptr;
+ const char* ldpreload_env = nullptr;
+ if (!getauxval(AT_SECURE)) {
+ ldpath_env = getenv("HYBRIS_LD_LIBRARY_PATH");
+ if (ldpath_env != nullptr) {
+ INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
+ }
+ ldpreload_env = getenv("HYBRIS_LD_PRELOAD");
+ if (ldpreload_env != nullptr) {
+ INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
+ }
+ }
+
+ struct stat file_stat;
+ // Stat "/proc/self/exe" instead of executable_path because
+ // the executable could be unlinked by this point and it should
+ // not cause a crash (see http://b/31084669)
+ if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) {
+ async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
+ }
+
+ const char* executable_path = get_executable_path();
+ soinfo* si = soinfo_alloc(g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
+ if (si == nullptr) {
+ async_safe_fatal("Couldn't allocate soinfo: out of memory?");
+ }
+
+ /* bootstrap the link map, the main exe always needs to be first */
+ si->set_main_executable();
+ link_map* map = &(si->link_map_head);
+
+ // Register the main executable and the linker upfront to have
+ // gdb aware of them before loading the rest of the dependency
+ // tree.
+ map->l_addr = 0;
+ map->l_name = const_cast<char*>(executable_path);
+ insert_link_map_into_debug_map(map);
+ insert_link_map_into_debug_map(&linker_link_map);
+
+ // Extract information passed from the kernel.
+ si->phdr = reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR));
+ si->phnum = args.getauxval(AT_PHNUM);
+
+ /* Compute the value of si->base. We can't rely on the fact that
+ * the first entry is the PHDR because this will not be true
+ * for certain executables (e.g. some in the NDK unit test suite)
+ */
+ si->base = 0;
+ si->size = phdr_table_get_load_size(si->phdr, si->phnum);
+ si->load_bias = 0;
+ for (size_t i = 0; i < si->phnum; ++i) {
+ if (si->phdr[i].p_type == PT_PHDR) {
+ si->load_bias = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_vaddr;
+ si->base = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_offset;
+ break;
+ }
+ }
+
+ if (si->base == 0) {
+ async_safe_fatal("Could not find a PHDR: broken executable?");
+ }
+
+ si->dynamic = nullptr;
+
+ ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
+
+ // We haven't supported non-PIE since Lollipop for security reasons.
+ if (elf_hdr->e_type != ET_DYN) {
+ // We don't use __libc_fatal here because we don't want a tombstone: it's
+ // been several years now but we still find ourselves on app compatibility
+ // investigations because some app's trying to launch an executable that
+ // hasn't worked in at least three years, and we've "helpfully" dropped a
+ // tombstone for them. The tombstone never provided any detail relevant to
+ // fixing the problem anyway, and the utility of drawing extra attention
+ // to the problem is non-existent at this late date.
+ fprintf(stderr,
+ "\"%s\": error: Android 5.0 and later only support "
+ "position-independent executables (-fPIE).\n",
+ g_argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
+ if (ldpath_env)
+ parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
+ parse_LD_PRELOAD(ldpreload_env);
+
+ somain = si;
+
+ std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
+
+ if (!si->prelink_image()) {
+ async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ }
+
+ // add somain to global group
+ si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+ // ... and add it to all other linked namespaces
+ for (auto linked_ns : namespaces) {
+ if (linked_ns != g_default_namespace) {
+ linked_ns->add_soinfo(somain);
+ somain->add_secondary_namespace(linked_ns);
+ }
+ }
+
+ // Load ld_preloads and dependencies.
+ std::vector<const char*> needed_library_name_list;
+ size_t ld_preloads_count = 0;
+
+ for (const auto& ld_preload_name : g_ld_preload_names) {
+ needed_library_name_list.push_back(ld_preload_name.c_str());
+ ++ld_preloads_count;
+ }
+
+ for_each_dt_needed(si, [&](const char* name) {
+ needed_library_name_list.push_back(name);
+ });
+
+ const char** needed_library_names = &needed_library_name_list[0];
+ size_t needed_libraries_count = needed_library_name_list.size();
+
+ // readers_map is shared across recursive calls to find_libraries so that we
+ // don't need to re-load elf headers.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
+ if (needed_libraries_count > 0 &&
+ !find_libraries(g_default_namespace,
+ si,
+ needed_library_names,
+ needed_libraries_count,
+ nullptr,
+ &g_ld_preloads,
+ ld_preloads_count,
+ RTLD_GLOBAL,
+ nullptr,
+ true /* add_as_children */,
+ true /* search_linked_namespaces */,
+ readers_map,
+ &namespaces)) {
+ fprintf(stderr, "CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ } else if (needed_libraries_count == 0) {
+ if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
+ fprintf(stderr, "CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ }
+ si->increment_ref_count();
+ }
+
+ add_vdso(args);
+
+ if (!get_cfi_shadow()->InitialLinkDone(solist)) {
+ fprintf(stderr, "CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ }
+
+ si->call_pre_init_constructors();
+
+ /* After the prelink_image, the si->load_bias is initialized.
+ * For so lib, the map->l_addr will be updated in notify_gdb_of_load.
+ * We need to update this value for so exe here. So Unwind_Backtrace
+ * for some arch like x86 could work correctly within so exe.
+ */
+ map->l_addr = si->load_bias;
+ si->call_constructors();
+
+#if TIMING
+ gettimeofday(&t1, nullptr);
+ PRINT("LINKER TIME: %s: %d microseconds", g_argv[0], (int) (
+ (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
+ (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec)));
+#endif
+#if STATS
+ PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", g_argv[0],
+ linker_stats.count[kRelocAbsolute],
+ linker_stats.count[kRelocRelative],
+ linker_stats.count[kRelocCopy],
+ linker_stats.count[kRelocSymbol]);
+#endif
+#if COUNT_PAGES
+ {
+ unsigned n;
+ unsigned i;
+ unsigned count = 0;
+ for (n = 0; n < 4096; n++) {
+ if (bitmask[n]) {
+ unsigned x = bitmask[n];
+#if defined(__LP64__)
+ for (i = 0; i < 32; i++) {
+#else
+ for (i = 0; i < 8; i++) {
+#endif
+ if (x & 1) {
+ count++;
+ }
+ x >>= 1;
+ }
+ }
+ }
+ PRINT("PAGES MODIFIED: %s: %d (%dKB)", g_argv[0], count, count * 4);
+ }
+#endif
+
+#if TIMING || STATS || COUNT_PAGES
+ fflush(stdout);
+#endif
+
+ ElfW(Addr) entry = args.getauxval(AT_ENTRY);
+ TRACE("[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(entry));
+ return entry;
+}
+
+/* Compute the load-bias of an existing executable. This shall only
+ * be used to compute the load bias of an executable or shared library
+ * that was loaded by the kernel itself.
+ *
+ * Input:
+ * elf -> address of ELF header, assumed to be at the start of the file.
+ * Return:
+ * load bias, i.e. add the value of any p_vaddr in the file to get
+ * the corresponding address in memory.
+ */
+static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
+ ElfW(Addr) offset = elf->e_phoff;
+ const ElfW(Phdr)* phdr_table =
+ reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
+ const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
+
+ for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {
+ if (phdr->p_type == PT_LOAD) {
+ return reinterpret_cast<ElfW(Addr)>(elf) + phdr->p_offset - phdr->p_vaddr;
+ }
+ }
+ return 0;
+}
+
+static void __linker_cannot_link(const char* argv0) {
+ async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+}
+
+void* (*_get_hooked_symbol)(const char *sym, const char *requester);
+void *(*_create_wrapper)(const char *symbol, void *function, int wrapper_type);
+
+#ifdef WANT_ARM_TRACING
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support, void *(create_wrapper)(const char*, void*, int)) {
+#else
+extern "C" void android_linker_init(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*), int enable_linker_gdb_support) {
+#endif
+ // Get a few environment variables.
+ const char* LD_DEBUG = getenv("HYBRIS_LD_DEBUG");
+ if (LD_DEBUG != nullptr) {
+ g_ld_debug_verbosity = atoi(LD_DEBUG);
+ }
+
+ const char* ldpath_env = nullptr;
+ const char* ldpreload_env = nullptr;
+ if (!getauxval(AT_SECURE)) {
+ ldpath_env = getenv("HYBRIS_LD_LIBRARY_PATH");
+ ldpreload_env = getenv("HYBRIS_LD_PRELOAD");
+ }
+
+ if (ldpath_env)
+ parse_LD_LIBRARY_PATH(ldpath_env);
+ else
+ parse_LD_LIBRARY_PATH(DEFAULT_HYBRIS_LD_LIBRARY_PATH);
+ parse_LD_PRELOAD(ldpreload_env);
+
+ if (sdk_version > 0)
+ set_application_target_sdk_version(sdk_version);
+
+ _get_hooked_symbol = get_hooked_symbol;
+ _linker_enable_gdb_support = enable_linker_gdb_support;
+#ifdef WANT_ARM_TRACING
+ _create_wrapper = create_wrapper;
+#endif
+
+ sonext = solist = get_libdl_info(kLinkerPath, linker_link_map);
+
+ init_default_namespaces(get_executable_path());
+}
+
+#ifdef DISABLED_FOR_HYBRIS_SUPPORT
+/*
+ * This is the entry point for the linker, called from begin.S. This
+ * method is responsible for fixing the linker's own relocations, and
+ * then calling __linker_init_post_relocation().
+ *
+ * Because this method is called before the linker has fixed it's own
+ * relocations, any attempt to reference an extern variable, extern
+ * function, or other GOT reference will generate a segfault.
+ */
+extern "C" ElfW(Addr) __linker_init(void* raw_args) {
+ KernelArgumentBlock args(raw_args);
+
+ // AT_BASE is set to 0 in the case when linker is run by iself
+ // so in order to link the linker it needs to calcuate AT_BASE
+ // using information at hand. The trick below takes advantage
+ // of the fact that the value of linktime_addr before relocations
+ // are run is an offset and this can be used to calculate AT_BASE.
+ static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
+ ElfW(Addr) linker_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
+
+#if defined(__clang_analyzer__)
+ // The analyzer assumes that linker_addr will always be null. Make it an
+ // unknown value so we don't have to mark N places with NOLINTs.
+ //
+ // (`+=`, rather than `=`, allows us to sidestep a potential "unused store"
+ // complaint)
+ linker_addr += reinterpret_cast<uintptr_t>(raw_args);
+#endif
+
+ ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
+ ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
+ ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
+
+ soinfo linker_so(nullptr, nullptr, nullptr, 0, 0);
+
+ linker_so.base = linker_addr;
+ linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
+ linker_so.load_bias = get_elf_exec_load_bias(elf_hdr);
+ linker_so.dynamic = nullptr;
+ linker_so.phdr = phdr;
+ linker_so.phnum = elf_hdr->e_phnum;
+ linker_so.set_linker_flag();
+
+ // Prelink the linker so we can access linker globals.
+ if (!linker_so.prelink_image()) __linker_cannot_link(args.argv[0]);
+
+ // This might not be obvious... The reasons why we pass g_empty_list
+ // in place of local_group here are (1) we do not really need it, because
+ // linker is built with DT_SYMBOLIC and therefore relocates its symbols against
+ // itself without having to look into local_group and (2) allocators
+ // are not yet initialized, and therefore we cannot use linked_list.push_*
+ // functions at this point.
+ if (!linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args.argv[0]);
+
+#if defined(__i386__)
+ // On x86, we can't make system calls before this point.
+ // We can't move this up because this needs to assign to a global.
+ // Note that until we call __libc_init_main_thread below we have
+ // no TLS, so you shouldn't make a system call that can fail, because
+ // it will SEGV when it tries to set errno.
+ __libc_init_sysinfo(args);
+#endif
+
+ // Initialize the main thread (including TLS, so system calls really work).
+ __libc_init_main_thread(args);
+
+ // We didn't protect the linker's RELRO pages in link_image because we
+ // couldn't make system calls on x86 at that point, but we can now...
+ if (!linker_so.protect_relro()) __linker_cannot_link(args.argv[0]);
+
+ // Initialize the linker's static libc's globals
+ __libc_init_globals(args);
+
+ // store argc/argv/envp to use them for calling constructors
+ g_argc = args.argc;
+ g_argv = args.argv;
+ g_envp = args.envp;
+
+ // Initialize the linker's own global variables
+ linker_so.call_constructors();
+
+ // If the linker is not acting as PT_INTERP entry_point is equal to
+ // _start. Which means that the linker is running as an executable and
+ // already linked by PT_INTERP.
+ //
+ // This happens when user tries to run 'adb shell /system/bin/linker'
+ // see also https://code.google.com/p/android/issues/detail?id=63174
+ if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
+ async_safe_format_fd(STDOUT_FILENO,
+ "This is %s, the helper program for dynamic executables.\n",
+ args.argv[0]);
+ exit(0);
+ }
+
+ init_linker_info_for_gdb(linker_addr, kLinkerPath);
+
+ // Initialize static variables. Note that in order to
+ // get correct libdl_info we need to call constructors
+ // before get_libdl_info().
+ sonext = solist = get_libdl_info(kLinkerPath, linker_link_map);
+ g_default_namespace->add_soinfo(solist);
+
+ // We have successfully fixed our own relocations. It's safe to run
+ // the main part of the linker now.
+ args.abort_message_ptr = &g_abort_message;
+ ElfW(Addr) start_address = __linker_init_post_relocation(args);
+
+ INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
+
+ // Return the address that the calling assembly stub should jump to.
+ return start_address;
+}
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_main.h
^
|
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_MAIN_H
+#define __LINKER_MAIN_H
+
+#include <android/dlext.h>
+
+#include <unordered_map>
+#include <vector>
+
+#include "linker_namespaces.h"
+#include "linker_soinfo.h"
+
+class ProtectedDataGuard {
+ public:
+ ProtectedDataGuard();
+ ~ProtectedDataGuard();
+
+ private:
+ void protect_data(int protection);
+ static size_t ref_count_;
+};
+
+class ElfReader;
+
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path);
+soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
+ struct stat* file_stat, off64_t file_offset,
+ uint32_t rtld_flags);
+
+bool find_libraries(android_namespace_t* ns,
+ soinfo* start_with,
+ const char* const library_names[],
+ size_t library_names_count,
+ soinfo* soinfos[],
+ std::vector<soinfo*>* ld_preloads,
+ size_t ld_preloads_count,
+ int rtld_flags,
+ const android_dlextinfo* extinfo,
+ bool add_as_children,
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces = nullptr);
+
+void solist_add_soinfo(soinfo* si);
+bool solist_remove_soinfo(soinfo* si);
+soinfo* solist_get_head();
+soinfo* solist_get_somain();
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_mapped_file_fragment.cpp
^
|
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_mapped_file_fragment.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "hybris_compat.h"
+
+MappedFileFragment::MappedFileFragment() : map_start_(nullptr), map_size_(0),
+ data_(nullptr), size_ (0)
+{ }
+
+MappedFileFragment::~MappedFileFragment() {
+ if (map_start_ != nullptr) {
+ munmap(map_start_, map_size_);
+ }
+}
+
+bool MappedFileFragment::Map(int fd, off64_t base_offset, size_t elf_offset, size_t size) {
+ off64_t offset;
+ CHECK(safe_add(&offset, base_offset, elf_offset));
+
+ off64_t page_min = page_start(offset);
+ off64_t end_offset;
+
+ CHECK(safe_add(&end_offset, offset, size));
+ CHECK(safe_add(&end_offset, end_offset, page_offset(offset)));
+
+ size_t map_size = static_cast<size_t>(end_offset - page_min);
+ CHECK(map_size >= size);
+
+ uint8_t* map_start = static_cast<uint8_t*>(
+ mmap64(nullptr, map_size, PROT_READ, MAP_PRIVATE, fd, page_min));
+
+ if (map_start == MAP_FAILED) {
+ return false;
+ }
+
+ map_start_ = map_start;
+ map_size_ = map_size;
+
+ data_ = map_start + page_offset(offset);
+ size_ = size;
+
+ return true;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_mapped_file_fragment.h
^
|
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef LINKER_MAPPED_FILE_FRAGMENT_H
+#define LINKER_MAPPED_FILE_FRAGMENT_H
+
+#include <unistd.h>
+
+#include "private/bionic_macros.h"
+
+class MappedFileFragment {
+ public:
+ MappedFileFragment();
+ ~MappedFileFragment();
+
+ bool Map(int fd, off64_t base_offset, size_t elf_offset, size_t size);
+
+ void* data() const { return data_; }
+ size_t size() const { return size_; }
+ private:
+ void* map_start_;
+ size_t map_size_;
+ void* data_;
+ size_t size_;
+
+ DISALLOW_COPY_AND_ASSIGN(MappedFileFragment);
+};
+
+#endif /* LINKER_MAPPED_FILE_FRAGMENT_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_memory.cpp
^
|
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_allocator.h"
+
+#include <stdlib.h>
+#include <sys/cdefs.h>
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+#if DISABLED_FOR_HYBRIS_SUPPORT
+static LinkerMemoryAllocator g_linker_allocator;
+static pid_t fallback_tid = 0;
+
+// Used by libdebuggerd_handler to switch allocators during a crash dump, in
+// case the linker heap is corrupted. Do not use this function.
+extern "C" void __linker_enable_fallback_allocator() {
+ if (fallback_tid != 0) {
+ async_safe_fatal("attempted to use currently-in-use fallback allocator");
+ }
+
+ fallback_tid = gettid();
+}
+
+extern "C" void __linker_disable_fallback_allocator() {
+ if (fallback_tid == 0) {
+ async_safe_fatal("attempted to disable unused fallback allocator");
+ }
+
+ fallback_tid = 0;
+}
+
+static LinkerMemoryAllocator& get_fallback_allocator() {
+ static LinkerMemoryAllocator fallback_allocator;
+ return fallback_allocator;
+}
+
+static LinkerMemoryAllocator& get_allocator() {
+ if (__predict_false(fallback_tid) && __predict_false(gettid() == fallback_tid)) {
+ return get_fallback_allocator();
+ }
+ return g_linker_allocator;
+}
+
+void* malloc(size_t byte_count) {
+ return get_allocator().alloc(byte_count);
+}
+
+void* calloc(size_t item_count, size_t item_size) {
+ return get_allocator().alloc(item_count*item_size);
+}
+
+void* realloc(void* p, size_t byte_count) {
+ return get_allocator().realloc(p, byte_count);
+}
+
+void free(void* ptr) {
+ get_allocator().free(ptr);
+}
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_namespaces.cpp
^
|
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_namespaces.h"
+#include "linker_globals.h"
+#include "linker_soinfo.h"
+#include "linker_utils.h"
+
+#include <dlfcn.h>
+
+#include "hybris_compat.h"
+
+bool android_namespace_t::is_accessible(const std::string& file) {
+ if (!is_isolated_) {
+ return true;
+ }
+
+ for (const auto& dir : ld_library_paths_) {
+ if (file_is_in_dir(file, dir)) {
+ return true;
+ }
+ }
+
+ for (const auto& dir : default_library_paths_) {
+ if (file_is_in_dir(file, dir)) {
+ return true;
+ }
+ }
+
+ for (const auto& dir : permitted_paths_) {
+ if (file_is_under_dir(file, dir)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool android_namespace_t::is_accessible(soinfo* s) {
+ auto is_accessible_ftor = [this] (soinfo* si) {
+ // This is workaround for apps hacking into soinfo list.
+ // and inserting their own entries into it. (http://b/37191433)
+ if (!si->has_min_version(3)) {
+ DL_WARN("invalid soinfo version for \"%s\"", si->get_soname());
+ return false;
+ }
+
+ if (si->get_primary_namespace() == this) {
+ return true;
+ }
+
+ const android_namespace_list_t& secondary_namespaces = si->get_secondary_namespaces();
+ if (secondary_namespaces.find(this) != secondary_namespaces.end()) {
+ return true;
+ }
+
+ return false;
+ };
+
+ if (is_accessible_ftor(s)) {
+ return true;
+ }
+
+ return !s->get_parents().visit([&](soinfo* si) {
+ return !is_accessible_ftor(si);
+ });
+}
+
+// TODO: this is slightly unusual way to construct
+// the global group for relocation. Not every RTLD_GLOBAL
+// library is included in this group for backwards-compatibility
+// reasons.
+//
+// This group consists of the main executable, LD_PRELOADs
+// and libraries with the DF_1_GLOBAL flag set.
+soinfo_list_t android_namespace_t::get_global_group() {
+ soinfo_list_t global_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ global_group.push_back(si);
+ }
+ });
+
+ return global_group;
+}
+
+// This function provides a list of libraries to be shared
+// by the namespace. For the default namespace this is the global
+// group (see get_global_group). For all others this is a group
+// of RTLD_GLOBAL libraries (which includes the global group from
+// the default namespace).
+soinfo_list_t android_namespace_t::get_shared_group() {
+ if (this == g_default_namespace) {
+ return get_global_group();
+ }
+
+ soinfo_list_t shared_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
+ shared_group.push_back(si);
+ }
+ });
+
+ return shared_group;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_namespaces.h
^
|
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_NAMESPACES_H
+#define __LINKER_NAMESPACES_H
+
+#include "linker_common_types.h"
+
+#include <string>
+#include <vector>
+#include <unordered_set>
+
+struct android_namespace_t;
+
+struct android_namespace_link_t {
+ public:
+ android_namespace_link_t(android_namespace_t* linked_namespace,
+ const std::unordered_set<std::string>& shared_lib_sonames)
+ : linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames)
+ {}
+
+ android_namespace_t* linked_namespace() const {
+ return linked_namespace_;
+ }
+
+ const std::unordered_set<std::string>& shared_lib_sonames() const {
+ return shared_lib_sonames_;
+ }
+
+ bool is_accessible(const char* soname) const {
+ return shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
+ }
+
+ private:
+ android_namespace_t* const linked_namespace_;
+ const std::unordered_set<std::string> shared_lib_sonames_;
+};
+
+struct android_namespace_t {
+ public:
+ android_namespace_t() : name_(nullptr), is_isolated_(false), is_greylist_enabled_(false) {}
+
+ const char* get_name() const { return name_; }
+ void set_name(const char* name) { name_ = name; }
+
+ bool is_isolated() const { return is_isolated_; }
+ void set_isolated(bool isolated) { is_isolated_ = isolated; }
+
+ bool is_greylist_enabled() const { return is_greylist_enabled_; }
+ void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; }
+
+ const std::vector<std::string>& get_ld_library_paths() const {
+ return ld_library_paths_;
+ }
+ void set_ld_library_paths(std::vector<std::string>&& library_paths) {
+ ld_library_paths_ = library_paths;
+ }
+
+ const std::vector<std::string>& get_default_library_paths() const {
+ return default_library_paths_;
+ }
+ void set_default_library_paths(std::vector<std::string>&& library_paths) {
+ default_library_paths_ = library_paths;
+ }
+ void set_default_library_paths(const std::vector<std::string>& library_paths) {
+ default_library_paths_ = library_paths;
+ }
+
+ const std::vector<std::string>& get_permitted_paths() const {
+ return permitted_paths_;
+ }
+ void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
+ permitted_paths_ = permitted_paths;
+ }
+ void set_permitted_paths(const std::vector<std::string>& permitted_paths) {
+ permitted_paths_ = permitted_paths;
+ }
+
+ const std::vector<android_namespace_link_t>& linked_namespaces() const {
+ return linked_namespaces_;
+ }
+ void add_linked_namespace(android_namespace_t* linked_namespace,
+ const std::unordered_set<std::string>& shared_lib_sonames) {
+ linked_namespaces_.push_back(android_namespace_link_t(linked_namespace, shared_lib_sonames));
+ }
+
+ void add_soinfo(soinfo* si) {
+ soinfo_list_.push_back(si);
+ }
+
+ void add_soinfos(const soinfo_list_t& soinfos) {
+ for (auto si : soinfos) {
+ add_soinfo(si);
+ }
+ }
+
+ void remove_soinfo(soinfo* si) {
+ soinfo_list_.remove_if([&](soinfo* candidate) {
+ return si == candidate;
+ });
+ }
+
+ const soinfo_list_t& soinfo_list() const { return soinfo_list_; }
+
+ // For isolated namespaces - checks if the file is on the search path;
+ // always returns true for not isolated namespace.
+ bool is_accessible(const std::string& path);
+
+ // Returns true if si is accessible from this namespace. A soinfo
+ // is considered accessible when it belongs to this namespace
+ // or one of it's parent soinfos belongs to this namespace.
+ bool is_accessible(soinfo* si);
+
+ soinfo_list_t get_global_group();
+ soinfo_list_t get_shared_group();
+
+ private:
+ const char* name_;
+ bool is_isolated_;
+ bool is_greylist_enabled_;
+ std::vector<std::string> ld_library_paths_;
+ std::vector<std::string> default_library_paths_;
+ std::vector<std::string> permitted_paths_;
+ // Loader looks into linked namespace if it was not able
+ // to find a library in this namespace. Note that library
+ // lookup in linked namespaces are limited by the list of
+ // shared sonames.
+ std::vector<android_namespace_link_t> linked_namespaces_;
+ soinfo_list_t soinfo_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
+};
+
+#endif /* __LINKER_NAMESPACES_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_phdr.cpp
^
|
@@ -0,0 +1,1118 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hybris_compat.h"
+
+#include "linker_phdr.h"
+
+#include <errno.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "linker.h"
+#include "linker_dlwarning.h"
+#include "linker_globals.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+
+#include <android/api-level.h>
+#include "private/bionic_prctl.h"
+#include "private/CFIShadow.h" // For kLibraryAlignment
+
+static int GetTargetElfMachine() {
+#if defined(__arm__)
+ return EM_ARM;
+#elif defined(__aarch64__)
+ return EM_AARCH64;
+#elif defined(__i386__)
+ return EM_386;
+#elif defined(__mips__)
+ return EM_MIPS;
+#elif defined(__x86_64__)
+ return EM_X86_64;
+#endif
+}
+
+/**
+ TECHNICAL NOTE ON ELF LOADING.
+
+ An ELF file's program header table contains one or more PT_LOAD
+ segments, which corresponds to portions of the file that need to
+ be mapped into the process' address space.
+
+ Each loadable segment has the following important properties:
+
+ p_offset -> segment file offset
+ p_filesz -> segment file size
+ p_memsz -> segment memory size (always >= p_filesz)
+ p_vaddr -> segment's virtual address
+ p_flags -> segment flags (e.g. readable, writable, executable)
+
+ We will ignore the p_paddr and p_align fields of ElfW(Phdr) for now.
+
+ The loadable segments can be seen as a list of [p_vaddr ... p_vaddr+p_memsz)
+ ranges of virtual addresses. A few rules apply:
+
+ - the virtual address ranges should not overlap.
+
+ - if a segment's p_filesz is smaller than its p_memsz, the extra bytes
+ between them should always be initialized to 0.
+
+ - ranges do not necessarily start or end at page boundaries. Two distinct
+ segments can have their start and end on the same page. In this case, the
+ page inherits the mapping flags of the latter segment.
+
+ Finally, the real load addrs of each segment is not p_vaddr. Instead the
+ loader decides where to load the first segment, then will load all others
+ relative to the first one to respect the initial range layout.
+
+ For example, consider the following list:
+
+ [ offset:0, filesz:0x4000, memsz:0x4000, vaddr:0x30000 ],
+ [ offset:0x4000, filesz:0x2000, memsz:0x8000, vaddr:0x40000 ],
+
+ This corresponds to two segments that cover these virtual address ranges:
+
+ 0x30000...0x34000
+ 0x40000...0x48000
+
+ If the loader decides to load the first segment at address 0xa0000000
+ then the segments' load address ranges will be:
+
+ 0xa0030000...0xa0034000
+ 0xa0040000...0xa0048000
+
+ In other words, all segments must be loaded at an address that has the same
+ constant offset from their p_vaddr value. This offset is computed as the
+ difference between the first segment's load address, and its p_vaddr value.
+
+ However, in practice, segments do _not_ start at page boundaries. Since we
+ can only memory-map at page boundaries, this means that the bias is
+ computed as:
+
+ load_bias = phdr0_load_address - PAGE_START(phdr0->p_vaddr)
+
+ (NOTE: The value must be used as a 32-bit unsigned integer, to deal with
+ possible wrap around UINT32_MAX for possible large p_vaddr values).
+
+ And that the phdr0_load_address must start at a page boundary, with
+ the segment's real content starting at:
+
+ phdr0_load_address + PAGE_OFFSET(phdr0->p_vaddr)
+
+ Note that ELF requires the following condition to make the mmap()-ing work:
+
+ PAGE_OFFSET(phdr0->p_vaddr) == PAGE_OFFSET(phdr0->p_offset)
+
+ The load_bias must be added to any p_vaddr value read from the ELF file to
+ determine the corresponding memory address.
+
+ **/
+
+#define MAYBE_MAP_FLAG(x, from, to) (((x) & (from)) ? (to) : 0)
+#define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
+ MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
+ MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
+
+ElfReader::ElfReader()
+ : did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
+ phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
+ strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
+ mapped_by_caller_(false) {
+}
+
+bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
+ if (did_read_) {
+ return true;
+ }
+ name_ = name;
+ fd_ = fd;
+ file_offset_ = file_offset;
+ file_size_ = file_size;
+
+ if (ReadElfHeader() &&
+ VerifyElfHeader() &&
+ ReadProgramHeaders() &&
+ ReadSectionHeaders() &&
+ ReadDynamicSection()) {
+ did_read_ = true;
+ }
+
+ return did_read_;
+}
+
+bool ElfReader::Load(const android_dlextinfo* extinfo) {
+ CHECK(did_read_);
+ if (did_load_) {
+ return true;
+ }
+ if (ReserveAddressSpace(extinfo) &&
+ LoadSegments() &&
+ FindPhdr()) {
+ did_load_ = true;
+ }
+
+ return did_load_;
+}
+
+const char* ElfReader::get_string(ElfW(Word) index) const {
+ CHECK(strtab_ != nullptr);
+ CHECK(index < strtab_size_);
+
+ return strtab_ + index;
+}
+
+bool ElfReader::ReadElfHeader() {
+ ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
+ if (rc < 0) {
+ DL_ERR("can't read file \"%s\": %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ if (rc != sizeof(header_)) {
+ DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_.c_str(),
+ static_cast<size_t>(rc));
+ return false;
+ }
+ return true;
+}
+
+static const char* EM_to_string(int em) {
+ if (em == EM_386) return "EM_386";
+ if (em == EM_AARCH64) return "EM_AARCH64";
+ if (em == EM_ARM) return "EM_ARM";
+ if (em == EM_MIPS) return "EM_MIPS";
+ if (em == EM_X86_64) return "EM_X86_64";
+ return "EM_???";
+}
+
+bool ElfReader::VerifyElfHeader() {
+ if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
+ DL_ERR("\"%s\" has bad ELF magic", name_.c_str());
+ return false;
+ }
+
+ // Try to give a clear diagnostic for ELF class mismatches, since they're
+ // an easy mistake to make during the 32-bit/64-bit transition period.
+ int elf_class = header_.e_ident[EI_CLASS];
+#if defined(__LP64__)
+ if (elf_class != ELFCLASS64) {
+ if (elf_class == ELFCLASS32) {
+ DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_.c_str());
+ } else {
+ DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
+ }
+ return false;
+ }
+#else
+ if (elf_class != ELFCLASS32) {
+ if (elf_class == ELFCLASS64) {
+ DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_.c_str());
+ } else {
+ DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
+ }
+ return false;
+ }
+#endif
+
+ if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
+ DL_ERR("\"%s\" not little-endian: %d", name_.c_str(), header_.e_ident[EI_DATA]);
+ return false;
+ }
+
+ if (header_.e_type != ET_DYN) {
+ DL_ERR("\"%s\" has unexpected e_type: %d", name_.c_str(), header_.e_type);
+ return false;
+ }
+
+ if (header_.e_version != EV_CURRENT) {
+ DL_ERR("\"%s\" has unexpected e_version: %d", name_.c_str(), header_.e_version);
+ return false;
+ }
+
+ if (header_.e_machine != GetTargetElfMachine()) {
+ DL_ERR("\"%s\" has unexpected e_machine: %d (%s)", name_.c_str(), header_.e_machine,
+ EM_to_string(header_.e_machine));
+ return false;
+ }
+
+ if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
+ // Fail if app is targeting Android O or above
+ if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
+ name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
+ return false;
+ }
+ DL_WARN("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
+ name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
+ add_dlwarning(name_.c_str(), "has invalid ELF header");
+ }
+
+ if (header_.e_shstrndx == 0) {
+ // Fail if app is targeting Android O or above
+ if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
+ return false;
+ }
+
+ DL_WARN("\"%s\" has invalid e_shstrndx", name_.c_str());
+ add_dlwarning(name_.c_str(), "has invalid ELF header");
+ }
+
+ return true;
+}
+
+bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment) {
+ off64_t range_start;
+ off64_t range_end;
+
+ // Only header can be located at the 0 offset... This function called to
+ // check DYNSYM and DYNAMIC sections and phdr/shdr - none of them can be
+ // at offset 0.
+
+ return offset > 0 &&
+ safe_add(&range_start, file_offset_, offset) &&
+ safe_add(&range_end, range_start, size) &&
+ (range_start < file_size_) &&
+ (range_end <= file_size_) &&
+ ((offset % alignment) == 0);
+}
+
+// Loads the program header table from an ELF file into a read-only private
+// anonymous mmap-ed block.
+bool ElfReader::ReadProgramHeaders() {
+ phdr_num_ = header_.e_phnum;
+
+ // Like the kernel, we only accept program header tables that
+ // are smaller than 64KiB.
+ if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
+ DL_ERR("\"%s\" has invalid e_phnum: %zd", name_.c_str(), phdr_num_);
+ return false;
+ }
+
+ // Boundary checks
+ size_t size = phdr_num_ * sizeof(ElfW(Phdr));
+ if (!CheckFileRange(header_.e_phoff, size, alignof(ElfW(Phdr)))) {
+ DL_ERR_AND_LOG("\"%s\" has invalid phdr offset/size: %zu/%zu",
+ name_.c_str(),
+ static_cast<size_t>(header_.e_phoff),
+ size);
+ return false;
+ }
+
+ if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
+ DL_ERR("\"%s\" phdr mmap failed: %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ phdr_table_ = static_cast<ElfW(Phdr)*>(phdr_fragment_.data());
+ return true;
+}
+
+bool ElfReader::ReadSectionHeaders() {
+ shdr_num_ = header_.e_shnum;
+
+ if (shdr_num_ == 0) {
+ DL_ERR_AND_LOG("\"%s\" has no section headers", name_.c_str());
+ return false;
+ }
+
+ size_t size = shdr_num_ * sizeof(ElfW(Shdr));
+ if (!CheckFileRange(header_.e_shoff, size, alignof(const ElfW(Shdr)))) {
+ DL_ERR_AND_LOG("\"%s\" has invalid shdr offset/size: %zu/%zu",
+ name_.c_str(),
+ static_cast<size_t>(header_.e_shoff),
+ size);
+ return false;
+ }
+
+ if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
+ DL_ERR("\"%s\" shdr mmap failed: %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ shdr_table_ = static_cast<const ElfW(Shdr)*>(shdr_fragment_.data());
+ return true;
+}
+
+bool ElfReader::ReadDynamicSection() {
+ // 1. Find .dynamic section (in section headers)
+ const ElfW(Shdr)* dynamic_shdr = nullptr;
+ for (size_t i = 0; i < shdr_num_; ++i) {
+ if (shdr_table_[i].sh_type == SHT_DYNAMIC) {
+ dynamic_shdr = &shdr_table_ [i];
+ break;
+ }
+ }
+
+ if (dynamic_shdr == nullptr) {
+ DL_ERR_AND_LOG("\"%s\" .dynamic section header was not found", name_.c_str());
+ return false;
+ }
+
+ // Make sure dynamic_shdr offset and size matches PT_DYNAMIC phdr
+ size_t pt_dynamic_offset = 0;
+ size_t pt_dynamic_filesz = 0;
+ for (size_t i = 0; i < phdr_num_; ++i) {
+ const ElfW(Phdr)* phdr = &phdr_table_[i];
+ if (phdr->p_type == PT_DYNAMIC) {
+ pt_dynamic_offset = phdr->p_offset;
+ pt_dynamic_filesz = phdr->p_filesz;
+ }
+ }
+
+ if (pt_dynamic_offset != dynamic_shdr->sh_offset) {
+ if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid offset: 0x%zx, "
+ "expected to match PT_DYNAMIC offset: 0x%zx",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_offset),
+ pt_dynamic_offset);
+ return false;
+ }
+ DL_WARN("\"%s\" .dynamic section has invalid offset: 0x%zx, "
+ "expected to match PT_DYNAMIC offset: 0x%zx",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_offset),
+ pt_dynamic_offset);
+ add_dlwarning(name_.c_str(), "invalid .dynamic section");
+ }
+
+ if (pt_dynamic_filesz != dynamic_shdr->sh_size) {
+ if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid size: 0x%zx, "
+ "expected to match PT_DYNAMIC filesz: 0x%zx",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_size),
+ pt_dynamic_filesz);
+ return false;
+ }
+ DL_WARN("\"%s\" .dynamic section has invalid size: 0x%zx, "
+ "expected to match PT_DYNAMIC filesz: 0x%zx",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_size),
+ pt_dynamic_filesz);
+ add_dlwarning(name_.c_str(), "invalid .dynamic section");
+ }
+
+ if (dynamic_shdr->sh_link >= shdr_num_) {
+ DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid sh_link: %d",
+ name_.c_str(),
+ dynamic_shdr->sh_link);
+ return false;
+ }
+
+ const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
+
+ if (strtab_shdr->sh_type != SHT_STRTAB) {
+ DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
+ name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
+ return false;
+ }
+
+ if (!CheckFileRange(dynamic_shdr->sh_offset, dynamic_shdr->sh_size, alignof(const ElfW(Dyn)))) {
+ DL_ERR_AND_LOG("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
+ return false;
+ }
+
+ if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
+ DL_ERR("\"%s\" dynamic section mmap failed: %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ dynamic_ = static_cast<const ElfW(Dyn)*>(dynamic_fragment_.data());
+
+ if (!CheckFileRange(strtab_shdr->sh_offset, strtab_shdr->sh_size, alignof(const char))) {
+ DL_ERR_AND_LOG("\"%s\" has invalid offset/size of the .strtab section linked from .dynamic section",
+ name_.c_str());
+ return false;
+ }
+
+ if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
+ DL_ERR("\"%s\" strtab section mmap failed: %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ strtab_ = static_cast<const char*>(strtab_fragment_.data());
+ strtab_size_ = strtab_fragment_.size();
+ return true;
+}
+
+/* Returns the size of the extent of all the possibly non-contiguous
+ * loadable segments in an ELF program header table. This corresponds
+ * to the page-aligned size in bytes that needs to be reserved in the
+ * process' address space. If there are no loadable segments, 0 is
+ * returned.
+ *
+ * If out_min_vaddr or out_max_vaddr are not null, they will be
+ * set to the minimum and maximum addresses of pages to be reserved,
+ * or 0 if there is nothing to load.
+ */
+size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr)* out_min_vaddr,
+ ElfW(Addr)* out_max_vaddr) {
+ ElfW(Addr) min_vaddr = UINTPTR_MAX;
+ ElfW(Addr) max_vaddr = 0;
+
+ bool found_pt_load = false;
+ for (size_t i = 0; i < phdr_count; ++i) {
+ const ElfW(Phdr)* phdr = &phdr_table[i];
+
+ if (phdr->p_type != PT_LOAD) {
+ continue;
+ }
+ found_pt_load = true;
+
+ if (phdr->p_vaddr < min_vaddr) {
+ min_vaddr = phdr->p_vaddr;
+ }
+
+ if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
+ max_vaddr = phdr->p_vaddr + phdr->p_memsz;
+ }
+ }
+ if (!found_pt_load) {
+ min_vaddr = 0;
+ }
+
+ min_vaddr = PAGE_START(min_vaddr);
+ max_vaddr = PAGE_END(max_vaddr);
+
+ if (out_min_vaddr != nullptr) {
+ *out_min_vaddr = min_vaddr;
+ }
+ if (out_max_vaddr != nullptr) {
+ *out_max_vaddr = max_vaddr;
+ }
+ return max_vaddr - min_vaddr;
+}
+
+// Reserve a virtual address range such that if it's limits were extended to the next 2**align
+// boundary, it would not overlap with any existing mappings.
+static void* ReserveAligned(void* hint, size_t size, size_t align) {
+ int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ // Address hint is only used in Art for the image mapping, and it is pretty important. Don't mess
+ // with it.
+ // FIXME: try an aligned allocation and fall back to plain mmap() if the former does not provide a
+ // mapping at the requested address?
+ if (align == PAGE_SIZE || hint != nullptr) {
+ void* mmap_ptr = mmap(hint, size, PROT_NONE, mmap_flags, -1, 0);
+ if (mmap_ptr == MAP_FAILED) {
+ return nullptr;
+ }
+ return mmap_ptr;
+ }
+
+ // Allocate enough space so that the end of the desired region aligned up is still inside the
+ // mapping.
+ size_t mmap_size = align_up(size, align) + align - PAGE_SIZE;
+ uint8_t* mmap_ptr =
+ reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
+ if (mmap_ptr == MAP_FAILED) {
+ return nullptr;
+ }
+
+ uint8_t* first = align_up(mmap_ptr, align);
+ uint8_t* last = align_down(mmap_ptr + mmap_size, align) - size;
+ size_t n = rand() % ((last - first) / PAGE_SIZE + 1);
+ uint8_t* start = first + n * PAGE_SIZE;
+ munmap(mmap_ptr, start - mmap_ptr);
+ munmap(start + size, mmap_ptr + mmap_size - (start + size));
+ return start;
+}
+
+// Reserve a virtual address range big enough to hold all loadable
+// segments of a program header table. This is done by creating a
+// private anonymous mmap() with PROT_NONE.
+bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
+ ElfW(Addr) min_vaddr;
+ load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
+ if (load_size_ == 0) {
+ DL_ERR("\"%s\" has no loadable segments", name_.c_str());
+ return false;
+ }
+
+ uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
+ void* start;
+ size_t reserved_size = 0;
+ bool reserved_hint = true;
+ bool strict_hint = false;
+ // Assume position independent executable by default.
+ void* mmap_hint = nullptr;
+
+ if (extinfo != nullptr) {
+ if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
+ reserved_size = extinfo->reserved_size;
+ reserved_hint = false;
+ } else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) {
+ reserved_size = extinfo->reserved_size;
+ }
+
+ if (addr != nullptr && (extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) {
+ mmap_hint = addr;
+ } else if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0) {
+ mmap_hint = extinfo->reserved_addr;
+ strict_hint = true;
+ }
+ }
+
+ if (load_size_ > reserved_size) {
+ if (!reserved_hint) {
+ DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
+ reserved_size - load_size_, load_size_, name_.c_str());
+ return false;
+ }
+ start = ReserveAligned(mmap_hint, load_size_, kLibraryAlignment);
+ if (start == nullptr) {
+ DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
+ return false;
+ }
+ if (strict_hint && (start != mmap_hint)) {
+ munmap(start, load_size_);
+ DL_ERR("couldn't reserve %zd bytes of address space at %p for \"%s\"",
+ load_size_, mmap_hint, name_.c_str());
+ return false;
+ }
+ } else {
+ start = extinfo->reserved_addr;
+ mapped_by_caller_ = true;
+ }
+
+ load_start_ = start;
+ load_bias_ = reinterpret_cast<uint8_t*>(start) - addr;
+ return true;
+}
+
+bool ElfReader::LoadSegments() {
+ for (size_t i = 0; i < phdr_num_; ++i) {
+ const ElfW(Phdr)* phdr = &phdr_table_[i];
+
+ if (phdr->p_type != PT_LOAD) {
+ continue;
+ }
+
+ // Segment addresses in memory.
+ ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
+ ElfW(Addr) seg_end = seg_start + phdr->p_memsz;
+
+ ElfW(Addr) seg_page_start = PAGE_START(seg_start);
+ ElfW(Addr) seg_page_end = PAGE_END(seg_end);
+
+ ElfW(Addr) seg_file_end = seg_start + phdr->p_filesz;
+
+ // File offsets.
+ ElfW(Addr) file_start = phdr->p_offset;
+ ElfW(Addr) file_end = file_start + phdr->p_filesz;
+
+ ElfW(Addr) file_page_start = PAGE_START(file_start);
+ ElfW(Addr) file_length = file_end - file_page_start;
+
+ if (file_size_ <= 0) {
+ DL_ERR("\"%s\" invalid file size: %" PRId64, name_.c_str(), file_size_);
+ return false;
+ }
+
+ if (file_end > static_cast<size_t>(file_size_)) {
+ DL_ERR("invalid ELF file \"%s\" load segment[%zd]:"
+ " p_offset (%p) + p_filesz (%p) ( = %p) past end of file (0x%" PRIx64 ")",
+ name_.c_str(), i, reinterpret_cast<void*>(phdr->p_offset),
+ reinterpret_cast<void*>(phdr->p_filesz),
+ reinterpret_cast<void*>(file_end), file_size_);
+ return false;
+ }
+
+ if (file_length != 0) {
+ int prot = PFLAGS_TO_PROT(phdr->p_flags);
+ if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
+ // W + E PT_LOAD segments are not allowed in O.
+ if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ DL_ERR_AND_LOG("\"%s\": W + E load segments are not allowed", name_.c_str());
+ return false;
+ }
+ DL_WARN("\"%s\": W + E load segments are not allowed", name_.c_str());
+ add_dlwarning(name_.c_str(), "W+E load segments");
+ }
+
+ void* seg_addr = mmap64(reinterpret_cast<void*>(seg_page_start),
+ file_length,
+ prot,
+ MAP_FIXED|MAP_PRIVATE,
+ fd_,
+ file_offset_ + file_page_start);
+ if (seg_addr == MAP_FAILED) {
+ DL_ERR("couldn't map \"%s\" segment %zd: %s", name_.c_str(), i, strerror(errno));
+ return false;
+ }
+ }
+
+ // if the segment is writable, and does not end on a page boundary,
+ // zero-fill it until the page limit.
+ if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
+ memset(reinterpret_cast<void*>(seg_file_end), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
+ }
+
+ seg_file_end = PAGE_END(seg_file_end);
+
+ // seg_file_end is now the first page address after the file
+ // content. If seg_end is larger, we need to zero anything
+ // between them. This is done by using a private anonymous
+ // map for all extra pages.
+ if (seg_page_end > seg_file_end) {
+ size_t zeromap_size = seg_page_end - seg_file_end;
+ void* zeromap = mmap(reinterpret_cast<void*>(seg_file_end),
+ zeromap_size,
+ PFLAGS_TO_PROT(phdr->p_flags),
+ MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
+ -1,
+ 0);
+ if (zeromap == MAP_FAILED) {
+ DL_ERR("couldn't zero fill \"%s\" gap: %s", name_.c_str(), strerror(errno));
+ return false;
+ }
+
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
+ }
+ }
+ return true;
+}
+
+/* Used internally. Used to set the protection bits of all loaded segments
+ * with optional extra flags (i.e. really PROT_WRITE). Used by
+ * phdr_table_protect_segments and phdr_table_unprotect_segments.
+ */
+static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, int extra_prot_flags) {
+ const ElfW(Phdr)* phdr = phdr_table;
+ const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
+
+ for (; phdr < phdr_limit; phdr++) {
+ if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_W) != 0) {
+ continue;
+ }
+
+ ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+
+ int prot = PFLAGS_TO_PROT(phdr->p_flags);
+ if ((extra_prot_flags & PROT_WRITE) != 0) {
+ // make sure we're never simultaneously writable / executable
+ prot &= ~PROT_EXEC;
+ }
+
+ int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
+ seg_page_end - seg_page_start,
+ prot | extra_prot_flags);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Restore the original protection modes for all loadable segments.
+ * You should only call this after phdr_table_unprotect_segments and
+ * applying all relocations.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Return:
+ * 0 on error, -1 on failure (error code in errno).
+ */
+int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count, ElfW(Addr) load_bias) {
+ return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, 0);
+}
+
+/* Change the protection of all loaded segments in memory to writable.
+ * This is useful before performing relocations. Once completed, you
+ * will have to call phdr_table_protect_segments to restore the original
+ * protection flags on all segments.
+ *
+ * Note that some writable segments can also have their content turned
+ * to read-only by calling phdr_table_protect_gnu_relro. This is no
+ * performed here.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Return:
+ * 0 on error, -1 on failure (error code in errno).
+ */
+int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count, ElfW(Addr) load_bias) {
+ return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, PROT_WRITE);
+}
+
+/* Used internally by phdr_table_protect_gnu_relro and
+ * phdr_table_unprotect_gnu_relro.
+ */
+static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, int prot_flags) {
+ const ElfW(Phdr)* phdr = phdr_table;
+ const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
+
+ for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
+ if (phdr->p_type != PT_GNU_RELRO) {
+ continue;
+ }
+
+ // Tricky: what happens when the relro segment does not start
+ // or end at page boundaries? We're going to be over-protective
+ // here and put every page touched by the segment as read-only.
+
+ // This seems to match Ian Lance Taylor's description of the
+ // feature at http://www.airs.com/blog/archives/189.
+
+ // Extract:
+ // Note that the current dynamic linker code will only work
+ // correctly if the PT_GNU_RELRO segment starts on a page
+ // boundary. This is because the dynamic linker rounds the
+ // p_vaddr field down to the previous page boundary. If
+ // there is anything on the page which should not be read-only,
+ // the program is likely to fail at runtime. So in effect the
+ // linker must only emit a PT_GNU_RELRO segment if it ensures
+ // that it starts on a page boundary.
+ ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+
+ int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
+ seg_page_end - seg_page_start,
+ prot_flags);
+ if (ret < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Apply GNU relro protection if specified by the program header. This will
+ * turn some of the pages of a writable PT_LOAD segment to read-only, as
+ * specified by one or more PT_GNU_RELRO segments. This must be always
+ * performed after relocations.
+ *
+ * The areas typically covered are .got and .data.rel.ro, these are
+ * read-only from the program's POV, but contain absolute addresses
+ * that need to be relocated before use.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Return:
+ * 0 on error, -1 on failure (error code in errno).
+ */
+int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count, ElfW(Addr) load_bias) {
+ return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ);
+}
+
+/* Serialize the GNU relro segments to the given file descriptor. This can be
+ * performed after relocations to allow another process to later share the
+ * relocated segment, if it was loaded at the same address.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * fd -> writable file descriptor to use
+ * Return:
+ * 0 on error, -1 on failure (error code in errno).
+ */
+int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count,
+ ElfW(Addr) load_bias,
+ int fd) {
+ const ElfW(Phdr)* phdr = phdr_table;
+ const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
+ ssize_t file_offset = 0;
+
+ for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
+ if (phdr->p_type != PT_GNU_RELRO) {
+ continue;
+ }
+
+ ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ssize_t size = seg_page_end - seg_page_start;
+
+ ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
+ if (written != size) {
+ return -1;
+ }
+ void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
+ MAP_PRIVATE|MAP_FIXED, fd, file_offset);
+ if (map == MAP_FAILED) {
+ return -1;
+ }
+ file_offset += size;
+ }
+ return 0;
+}
+
+/* Where possible, replace the GNU relro segments with mappings of the given
+ * file descriptor. This can be performed after relocations to allow a file
+ * previously created by phdr_table_serialize_gnu_relro in another process to
+ * replace the dirty relocated pages, saving memory, if it was loaded at the
+ * same address. We have to compare the data before we map over it, since some
+ * parts of the relro segment may not be identical due to other libraries in
+ * the process being loaded at different addresses.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * fd -> readable file descriptor to use
+ * Return:
+ * 0 on error, -1 on failure (error code in errno).
+ */
+int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count,
+ ElfW(Addr) load_bias,
+ int fd) {
+ // Map the file at a temporary location so we can compare its contents.
+ struct stat file_stat;
+ if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
+ return -1;
+ }
+ off_t file_size = file_stat.st_size;
+ void* temp_mapping = nullptr;
+ if (file_size > 0) {
+ temp_mapping = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (temp_mapping == MAP_FAILED) {
+ return -1;
+ }
+ }
+ size_t file_offset = 0;
+
+ // Iterate over the relro segments and compare/remap the pages.
+ const ElfW(Phdr)* phdr = phdr_table;
+ const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
+
+ for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
+ if (phdr->p_type != PT_GNU_RELRO) {
+ continue;
+ }
+
+ ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+
+ char* file_base = static_cast<char*>(temp_mapping) + file_offset;
+ char* mem_base = reinterpret_cast<char*>(seg_page_start);
+ size_t match_offset = 0;
+ size_t size = seg_page_end - seg_page_start;
+
+ if (file_size - file_offset < size) {
+ // File is too short to compare to this segment. The contents are likely
+ // different as well (it's probably for a different library version) so
+ // just don't bother checking.
+ break;
+ }
+
+ while (match_offset < size) {
+ // Skip over dissimilar pages.
+ while (match_offset < size &&
+ memcmp(mem_base + match_offset, file_base + match_offset, PAGE_SIZE) != 0) {
+ match_offset += PAGE_SIZE;
+ }
+
+ // Count similar pages.
+ size_t mismatch_offset = match_offset;
+ while (mismatch_offset < size &&
+ memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, PAGE_SIZE) == 0) {
+ mismatch_offset += PAGE_SIZE;
+ }
+
+ // Map over similar pages.
+ if (mismatch_offset > match_offset) {
+ void* map = mmap(mem_base + match_offset, mismatch_offset - match_offset,
+ PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, match_offset);
+ if (map == MAP_FAILED) {
+ munmap(temp_mapping, file_size);
+ return -1;
+ }
+ }
+
+ match_offset = mismatch_offset;
+ }
+
+ // Add to the base file offset in case there are multiple relro segments.
+ file_offset += size;
+ }
+ munmap(temp_mapping, file_size);
+ return 0;
+}
+
+
+#if defined(__arm__)
+
+# ifndef PT_ARM_EXIDX
+# define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
+# endif
+
+/* Return the address and size of the .ARM.exidx section in memory,
+ * if present.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Output:
+ * arm_exidx -> address of table in memory (null on failure).
+ * arm_exidx_count -> number of items in table (0 on failure).
+ * Return:
+ * 0 on error, -1 on failure (_no_ error code in errno)
+ */
+int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias,
+ ElfW(Addr)** arm_exidx, size_t* arm_exidx_count) {
+ const ElfW(Phdr)* phdr = phdr_table;
+ const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
+
+ for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
+ if (phdr->p_type != PT_ARM_EXIDX) {
+ continue;
+ }
+
+ *arm_exidx = reinterpret_cast<ElfW(Addr)*>(load_bias + phdr->p_vaddr);
+ *arm_exidx_count = phdr->p_memsz / 8;
+ return 0;
+ }
+ *arm_exidx = nullptr;
+ *arm_exidx_count = 0;
+ return -1;
+}
+#endif
+
+/* Return the address and size of the ELF file's .dynamic section in memory,
+ * or null if missing.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Output:
+ * dynamic -> address of table in memory (null on failure).
+ * dynamic_flags -> protection flags for section (unset on failure)
+ * Return:
+ * void
+ */
+void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
+ ElfW(Word)* dynamic_flags) {
+ *dynamic = nullptr;
+ for (size_t i = 0; i<phdr_count; ++i) {
+ const ElfW(Phdr)& phdr = phdr_table[i];
+ if (phdr.p_type == PT_DYNAMIC) {
+ *dynamic = reinterpret_cast<ElfW(Dyn)*>(load_bias + phdr.p_vaddr);
+ if (dynamic_flags) {
+ *dynamic_flags = phdr.p_flags;
+ }
+ return;
+ }
+ }
+}
+
+/* Return the program interpreter string, or nullptr if missing.
+ *
+ * Input:
+ * phdr_table -> program header table
+ * phdr_count -> number of entries in tables
+ * load_bias -> load bias
+ * Return:
+ * pointer to the program interpreter string.
+ */
+const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias) {
+ for (size_t i = 0; i<phdr_count; ++i) {
+ const ElfW(Phdr)& phdr = phdr_table[i];
+ if (phdr.p_type == PT_INTERP) {
+ return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
+ }
+ }
+ return nullptr;
+}
+
+// Sets loaded_phdr_ to the address of the program header table as it appears
+// in the loaded segments in memory. This is in contrast with phdr_table_,
+// which is temporary and will be released before the library is relocated.
+bool ElfReader::FindPhdr() {
+ const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
+
+ // If there is a PT_PHDR, use it directly.
+ for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
+ if (phdr->p_type == PT_PHDR) {
+ return CheckPhdr(load_bias_ + phdr->p_vaddr);
+ }
+ }
+
+ // Otherwise, check the first loadable segment. If its file offset
+ // is 0, it starts with the ELF header, and we can trivially find the
+ // loaded program header from it.
+ for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
+ if (phdr->p_type == PT_LOAD) {
+ if (phdr->p_offset == 0) {
+ ElfW(Addr) elf_addr = load_bias_ + phdr->p_vaddr;
+ const ElfW(Ehdr)* ehdr = reinterpret_cast<const ElfW(Ehdr)*>(elf_addr);
+ ElfW(Addr) offset = ehdr->e_phoff;
+ return CheckPhdr(reinterpret_cast<ElfW(Addr)>(ehdr) + offset);
+ }
+ break;
+ }
+ }
+
+ DL_ERR("can't find loaded phdr for \"%s\"", name_.c_str());
+ return false;
+}
+
+// Ensures that our program header is actually within a loadable
+// segment. This should help catch badly-formed ELF files that
+// would cause the linker to crash later when trying to access it.
+bool ElfReader::CheckPhdr(ElfW(Addr) loaded) {
+ const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
+ ElfW(Addr) loaded_end = loaded + (phdr_num_ * sizeof(ElfW(Phdr)));
+ for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
+ if (phdr->p_type != PT_LOAD) {
+ continue;
+ }
+ ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
+ ElfW(Addr) seg_end = phdr->p_filesz + seg_start;
+ if (seg_start <= loaded && loaded_end <= seg_end) {
+ loaded_phdr_ = reinterpret_cast<const ElfW(Phdr)*>(loaded);
+ return true;
+ }
+ }
+ DL_ERR("\"%s\" loaded phdr %p not in loadable segment",
+ name_.c_str(), reinterpret_cast<void*>(loaded));
+ return false;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_phdr.h
^
|
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef LINKER_PHDR_H
+#define LINKER_PHDR_H
+
+/* Declarations related to the ELF program header table and segments.
+ *
+ * The design goal is to provide an API that is as close as possible
+ * to the ELF spec, and does not depend on linker-specific data
+ * structures (e.g. the exact layout of struct soinfo).
+ */
+
+#include "linker.h"
+#include "linker_mapped_file_fragment.h"
+
+class ElfReader {
+ public:
+ ElfReader();
+
+ bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size);
+ bool Load(const android_dlextinfo* extinfo);
+
+ const char* name() const { return name_.c_str(); }
+ size_t phdr_count() const { return phdr_num_; }
+ ElfW(Addr) load_start() const { return reinterpret_cast<ElfW(Addr)>(load_start_); }
+ size_t load_size() const { return load_size_; }
+ ElfW(Addr) load_bias() const { return load_bias_; }
+ const ElfW(Phdr)* loaded_phdr() const { return loaded_phdr_; }
+ const ElfW(Dyn)* dynamic() const { return dynamic_; }
+ const char* get_string(ElfW(Word) index) const;
+ bool is_mapped_by_caller() const { return mapped_by_caller_; }
+
+ private:
+ bool ReadElfHeader();
+ bool VerifyElfHeader();
+ bool ReadProgramHeaders();
+ bool ReadSectionHeaders();
+ bool ReadDynamicSection();
+ bool ReserveAddressSpace(const android_dlextinfo* extinfo);
+ bool LoadSegments();
+ bool FindPhdr();
+ bool CheckPhdr(ElfW(Addr));
+ bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment);
+
+ bool did_read_;
+ bool did_load_;
+ std::string name_;
+ int fd_;
+ off64_t file_offset_;
+ off64_t file_size_;
+
+ ElfW(Ehdr) header_;
+ size_t phdr_num_;
+
+ MappedFileFragment phdr_fragment_;
+ const ElfW(Phdr)* phdr_table_;
+
+ MappedFileFragment shdr_fragment_;
+ const ElfW(Shdr)* shdr_table_;
+ size_t shdr_num_;
+
+ MappedFileFragment dynamic_fragment_;
+ const ElfW(Dyn)* dynamic_;
+
+ MappedFileFragment strtab_fragment_;
+ const char* strtab_;
+ size_t strtab_size_;
+
+ // First page of reserved address space.
+ void* load_start_;
+ // Size in bytes of reserved address space.
+ size_t load_size_;
+ // Load bias.
+ ElfW(Addr) load_bias_;
+
+ // Loaded phdr.
+ const ElfW(Phdr)* loaded_phdr_;
+
+ // Is map owned by the caller
+ bool mapped_by_caller_;
+};
+
+size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr)* min_vaddr = nullptr, ElfW(Addr)* max_vaddr = nullptr);
+
+int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table,
+ size_t phdr_count, ElfW(Addr) load_bias);
+
+int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias);
+
+int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias);
+
+int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, int fd);
+
+int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, int fd);
+
+#if defined(__arm__)
+int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count, ElfW(Addr) load_bias,
+ ElfW(Addr)** arm_exidx, size_t* arm_exidix_count);
+#endif
+
+void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
+ ElfW(Word)* dynamic_flags);
+
+const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias);
+
+#endif /* LINKER_PHDR_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_reloc_iterators.h
^
|
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_RELOC_ITERATORS_H
+#define __LINKER_RELOC_ITERATORS_H
+
+#include "linker.h"
+
+#include <string.h>
+
+const size_t RELOCATION_GROUPED_BY_INFO_FLAG = 1;
+const size_t RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG = 2;
+const size_t RELOCATION_GROUPED_BY_ADDEND_FLAG = 4;
+const size_t RELOCATION_GROUP_HAS_ADDEND_FLAG = 8;
+
+class plain_reloc_iterator {
+#if defined(USE_RELA)
+ typedef ElfW(Rela) rel_t;
+#else
+ typedef ElfW(Rel) rel_t;
+#endif
+ public:
+ plain_reloc_iterator(rel_t* rel_array, size_t count)
+ : begin_(rel_array), end_(begin_ + count), current_(begin_) {}
+
+ bool has_next() {
+ return current_ < end_;
+ }
+
+ rel_t* next() {
+ return current_++;
+ }
+ private:
+ rel_t* const begin_;
+ rel_t* const end_;
+ rel_t* current_;
+
+ DISALLOW_COPY_AND_ASSIGN(plain_reloc_iterator);
+};
+
+template <typename decoder_t>
+class packed_reloc_iterator {
+#if defined(USE_RELA)
+ typedef ElfW(Rela) rel_t;
+#else
+ typedef ElfW(Rel) rel_t;
+#endif
+ public:
+ explicit packed_reloc_iterator(decoder_t&& decoder)
+ : decoder_(decoder) {
+ // initialize fields
+ memset(&reloc_, 0, sizeof(reloc_));
+ relocation_count_ = decoder_.pop_front();
+ reloc_.r_offset = decoder_.pop_front();
+ relocation_index_ = 0;
+ relocation_group_index_ = 0;
+ group_size_ = 0;
+ }
+
+ bool has_next() const {
+ return relocation_index_ < relocation_count_;
+ }
+
+ rel_t* next() {
+ if (relocation_group_index_ == group_size_) {
+ if (!read_group_fields()) {
+ // Iterator is inconsistent state; it should not be called again
+ // but in case it is let's make sure has_next() returns false.
+ relocation_index_ = relocation_count_ = 0;
+ return nullptr;
+ }
+ }
+
+ if (is_relocation_grouped_by_offset_delta()) {
+ reloc_.r_offset += group_r_offset_delta_;
+ } else {
+ reloc_.r_offset += decoder_.pop_front();
+ }
+
+ if (!is_relocation_grouped_by_info()) {
+ reloc_.r_info = decoder_.pop_front();
+ }
+
+#if defined(USE_RELA)
+ if (is_relocation_group_has_addend() &&
+ !is_relocation_grouped_by_addend()) {
+ reloc_.r_addend += decoder_.pop_front();
+ }
+#endif
+
+ relocation_index_++;
+ relocation_group_index_++;
+
+ return &reloc_;
+ }
+ private:
+ bool read_group_fields() {
+ group_size_ = decoder_.pop_front();
+ group_flags_ = decoder_.pop_front();
+
+ if (is_relocation_grouped_by_offset_delta()) {
+ group_r_offset_delta_ = decoder_.pop_front();
+ }
+
+ if (is_relocation_grouped_by_info()) {
+ reloc_.r_info = decoder_.pop_front();
+ }
+
+ if (is_relocation_group_has_addend() &&
+ is_relocation_grouped_by_addend()) {
+#if !defined(USE_RELA)
+ // This platform does not support rela, and yet we have it encoded in android_rel section.
+ DL_ERR("unexpected r_addend in android.rel section");
+ return false;
+#else
+ reloc_.r_addend += decoder_.pop_front();
+ } else if (!is_relocation_group_has_addend()) {
+ reloc_.r_addend = 0;
+#endif
+ }
+
+ relocation_group_index_ = 0;
+ return true;
+ }
+
+ bool is_relocation_grouped_by_info() {
+ return (group_flags_ & RELOCATION_GROUPED_BY_INFO_FLAG) != 0;
+ }
+
+ bool is_relocation_grouped_by_offset_delta() {
+ return (group_flags_ & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) != 0;
+ }
+
+ bool is_relocation_grouped_by_addend() {
+ return (group_flags_ & RELOCATION_GROUPED_BY_ADDEND_FLAG) != 0;
+ }
+
+ bool is_relocation_group_has_addend() {
+ return (group_flags_ & RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0;
+ }
+
+ decoder_t decoder_;
+ size_t relocation_count_;
+ size_t group_size_;
+ size_t group_flags_;
+ size_t group_r_offset_delta_;
+ size_t relocation_index_;
+ size_t relocation_group_index_;
+ rel_t reloc_;
+};
+
+#endif // __LINKER_RELOC_ITERATORS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_relocs.h
^
|
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_RELOCS_H
+#define __LINKER_RELOCS_H
+
+#include <elf.h>
+
+#define R_GENERIC_NONE 0 // R_*_NONE is always 0
+
+#if defined (__aarch64__)
+
+#define R_GENERIC_JUMP_SLOT R_AARCH64_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT R_AARCH64_GLOB_DAT
+#define R_GENERIC_RELATIVE R_AARCH64_RELATIVE
+#define R_GENERIC_IRELATIVE R_AARCH64_IRELATIVE
+
+#elif defined (__arm__)
+
+#define R_GENERIC_JUMP_SLOT R_ARM_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT R_ARM_GLOB_DAT
+#define R_GENERIC_RELATIVE R_ARM_RELATIVE
+#define R_GENERIC_IRELATIVE R_ARM_IRELATIVE
+
+#elif defined (__i386__)
+
+#define R_GENERIC_JUMP_SLOT R_386_JMP_SLOT
+#define R_GENERIC_GLOB_DAT R_386_GLOB_DAT
+#define R_GENERIC_RELATIVE R_386_RELATIVE
+#define R_GENERIC_IRELATIVE R_386_IRELATIVE
+
+#elif defined (__x86_64__)
+
+#define R_GENERIC_JUMP_SLOT R_X86_64_JUMP_SLOT
+#define R_GENERIC_GLOB_DAT R_X86_64_GLOB_DAT
+#define R_GENERIC_RELATIVE R_X86_64_RELATIVE
+#define R_GENERIC_IRELATIVE R_X86_64_IRELATIVE
+
+#endif
+
+#endif // __LINKER_RELOCS_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_sdk_versions.cpp
^
|
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker.h"
+#include <android/api-level.h>
+#include <atomic>
+
+static std::atomic<uint32_t> g_target_sdk_version(__ANDROID_API__);
+
+void set_application_target_sdk_version(uint32_t target) {
+ // translate current sdk_version to platform sdk_version
+ if (target == 0) {
+ target = __ANDROID_API__;
+ }
+ g_target_sdk_version = target;
+}
+
+uint32_t get_application_target_sdk_version() {
+ return g_target_sdk_version;
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_sleb128.h
^
|
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_SLEB128_H
+#define _LINKER_SLEB128_H
+
+#include <stdint.h>
+
+#include <async_safe/log.h>
+
+#include "linker_debug.h"
+
+// Helper classes for decoding LEB128, used in packed relocation data.
+// http://en.wikipedia.org/wiki/LEB128
+
+class sleb128_decoder {
+ public:
+ sleb128_decoder(const uint8_t* buffer, size_t count)
+ : current_(buffer), end_(buffer+count) { }
+
+ size_t pop_front() {
+ size_t value = 0;
+ static const size_t size = CHAR_BIT * sizeof(value);
+
+ size_t shift = 0;
+ uint8_t byte;
+
+ do {
+ if (current_ >= end_) {
+ async_safe_fatal("sleb128_decoder ran out of bounds");
+ }
+ byte = *current_++;
+ value |= (static_cast<size_t>(byte & 127) << shift);
+ shift += 7;
+ } while (byte & 128);
+
+ if (shift < size && (byte & 64)) {
+ value |= -(static_cast<size_t>(1) << shift);
+ }
+
+ return value;
+ }
+
+ private:
+ const uint8_t* current_;
+ const uint8_t* const end_;
+};
+
+#endif // __LINKER_SLEB128_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_soinfo.cpp
^
|
@@ -0,0 +1,811 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_soinfo.h"
+
+#include <dlfcn.h>
+#include <elf.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <async_safe/log.h>
+#include <android/api-level.h>
+
+#include "linker_debug.h"
+#include "linker_globals.h"
+#include "linker_logger.h"
+#include "linker_utils.h"
+
+#include "hybris_compat.h"
+
+#define ELF_ST_TYPE(x) ((x) & 0xf)
+
+// TODO(dimitry): These functions are currently located in linker.cpp - find a better place for it
+bool find_verdef_version_index(const soinfo* si, const version_info* vi, ElfW(Versym)* versym);
+ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr);
+uint32_t get_application_target_sdk_version();
+
+soinfo::soinfo(android_namespace_t* ns, const char* realpath,
+ const struct stat* file_stat, off64_t file_offset,
+ int rtld_flags) {
+
+ if (realpath != nullptr) {
+ realpath_ = realpath;
+ }
+
+ flags_ = FLAG_NEW_SOINFO;
+ version_ = SOINFO_VERSION;
+
+ if (file_stat != nullptr) {
+ this->st_dev_ = file_stat->st_dev;
+ this->st_ino_ = file_stat->st_ino;
+ this->file_offset_ = file_offset;
+ }
+
+ this->rtld_flags_ = rtld_flags;
+ this->primary_namespace_ = ns;
+}
+
+soinfo::~soinfo() {
+ g_soinfo_handles_map.erase(handle_);
+}
+
+void soinfo::set_dt_runpath(const char* path) {
+ if (!has_min_version(3)) {
+ return;
+ }
+
+ std::vector<std::string> runpaths;
+
+ split_path(path, ":", &runpaths);
+
+ std::string origin = dirname(get_realpath());
+ // FIXME: add $LIB and $PLATFORM.
+ std::vector<std::pair<std::string, std::string>> params = {{"ORIGIN", origin}};
+ for (auto&& s : runpaths) {
+ format_string(&s, params);
+ }
+
+ resolve_paths(runpaths, &dt_runpath_);
+}
+
+const ElfW(Versym)* soinfo::get_versym(size_t n) const {
+ if (has_min_version(2) && versym_ != nullptr) {
+ return versym_ + n;
+ }
+
+ return nullptr;
+}
+
+ElfW(Addr) soinfo::get_verneed_ptr() const {
+ if (has_min_version(2)) {
+ return verneed_ptr_;
+ }
+
+ return 0;
+}
+
+size_t soinfo::get_verneed_cnt() const {
+ if (has_min_version(2)) {
+ return verneed_cnt_;
+ }
+
+ return 0;
+}
+
+ElfW(Addr) soinfo::get_verdef_ptr() const {
+ if (has_min_version(2)) {
+ return verdef_ptr_;
+ }
+
+ return 0;
+}
+
+size_t soinfo::get_verdef_cnt() const {
+ if (has_min_version(2)) {
+ return verdef_cnt_;
+ }
+
+ return 0;
+}
+
+bool soinfo::find_symbol_by_name(SymbolName& symbol_name,
+ const version_info* vi,
+ const ElfW(Sym)** symbol) const {
+ uint32_t symbol_index;
+ bool success =
+ is_gnu_hash() ?
+ gnu_lookup(symbol_name, vi, &symbol_index) :
+ elf_lookup(symbol_name, vi, &symbol_index);
+
+ if (success) {
+ *symbol = symbol_index == 0 ? nullptr : symtab_ + symbol_index;
+ }
+
+ return success;
+}
+
+static bool is_symbol_global_and_defined(const soinfo* si, const ElfW(Sym)* s) {
+ if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
+ ELF_ST_BIND(s->st_info) == STB_WEAK) {
+ return s->st_shndx != SHN_UNDEF;
+ } else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
+ DL_WARN("unexpected ST_BIND value: %d for \"%s\" in \"%s\"",
+ ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
+ }
+
+ return false;
+}
+
+static const ElfW(Versym) kVersymHiddenBit = 0x8000;
+
+static inline bool is_versym_hidden(const ElfW(Versym)* versym) {
+ // the symbol is hidden if bit 15 of versym is set.
+ return versym != nullptr && (*versym & kVersymHiddenBit) != 0;
+}
+
+static inline bool check_symbol_version(const ElfW(Versym) verneed,
+ const ElfW(Versym)* verdef) {
+ return verneed == kVersymNotNeeded ||
+ verdef == nullptr ||
+ verneed == (*verdef & ~kVersymHiddenBit);
+}
+
+bool soinfo::gnu_lookup(SymbolName& symbol_name,
+ const version_info* vi,
+ uint32_t* symbol_index) const {
+ uint32_t hash = symbol_name.gnu_hash();
+ uint32_t h2 = hash >> gnu_shift2_;
+
+ uint32_t bloom_mask_bits = sizeof(ElfW(Addr))*8;
+ uint32_t word_num = (hash / bloom_mask_bits) & gnu_maskwords_;
+ ElfW(Addr) bloom_word = gnu_bloom_filter_[word_num];
+
+ *symbol_index = 0;
+
+ TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
+
+ // test against bloom filter
+ if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & (bloom_word >> (h2 % bloom_mask_bits))) == 0) {
+ TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
+
+ return true;
+ }
+
+ // bloom test says "probably yes"...
+ uint32_t n = gnu_bucket_[hash % gnu_nbucket_];
+
+ if (n == 0) {
+ TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
+
+ return true;
+ }
+
+ // lookup versym for the version definition in this library
+ // note the difference between "version is not requested" (vi == nullptr)
+ // and "version not found". In the first case verneed is kVersymNotNeeded
+ // which implies that the default version can be accepted; the second case results in
+ // verneed = 1 (kVersymGlobal) and implies that we should ignore versioned symbols
+ // for this library and consider only *global* ones.
+ ElfW(Versym) verneed = 0;
+ if (!find_verdef_version_index(this, vi, &verneed)) {
+ return false;
+ }
+
+ do {
+ ElfW(Sym)* s = symtab_ + n;
+ const ElfW(Versym)* verdef = get_versym(n);
+ // skip hidden versions when verneed == kVersymNotNeeded (0)
+ if (verneed == kVersymNotNeeded && is_versym_hidden(verdef)) {
+ continue;
+ }
+ if (((gnu_chain_[n] ^ hash) >> 1) == 0 &&
+ check_symbol_version(verneed, verdef) &&
+ strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
+ is_symbol_global_and_defined(this, s)) {
+ TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
+ static_cast<size_t>(s->st_size));
+ *symbol_index = n;
+ return true;
+ }
+ } while ((gnu_chain_[n++] & 1) == 0);
+
+ TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
+
+ return true;
+}
+
+bool soinfo::elf_lookup(SymbolName& symbol_name,
+ const version_info* vi,
+ uint32_t* symbol_index) const {
+ uint32_t hash = symbol_name.elf_hash();
+
+ TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
+ symbol_name.get_name(), get_realpath(),
+ reinterpret_cast<void*>(base), hash, hash % nbucket_);
+
+ ElfW(Versym) verneed = 0;
+ if (!find_verdef_version_index(this, vi, &verneed)) {
+ return false;
+ }
+
+ for (uint32_t n = bucket_[hash % nbucket_]; n != 0; n = chain_[n]) {
+ ElfW(Sym)* s = symtab_ + n;
+ const ElfW(Versym)* verdef = get_versym(n);
+
+ // skip hidden versions when verneed == 0
+ if (verneed == kVersymNotNeeded && is_versym_hidden(verdef)) {
+ continue;
+ }
+
+ if (check_symbol_version(verneed, verdef) &&
+ strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
+ is_symbol_global_and_defined(this, s)) {
+ TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
+ symbol_name.get_name(), get_realpath(),
+ reinterpret_cast<void*>(s->st_value),
+ static_cast<size_t>(s->st_size));
+ *symbol_index = n;
+ return true;
+ }
+ }
+
+ TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
+ symbol_name.get_name(), get_realpath(),
+ reinterpret_cast<void*>(base), hash, hash % nbucket_);
+
+ *symbol_index = 0;
+ return true;
+}
+
+ElfW(Sym)* soinfo::find_symbol_by_address(const void* addr) {
+ return is_gnu_hash() ? gnu_addr_lookup(addr) : elf_addr_lookup(addr);
+}
+
+static bool symbol_matches_soaddr(const ElfW(Sym)* sym, ElfW(Addr) soaddr) {
+ return sym->st_shndx != SHN_UNDEF &&
+ soaddr >= sym->st_value &&
+ soaddr < sym->st_value + sym->st_size;
+}
+
+ElfW(Sym)* soinfo::gnu_addr_lookup(const void* addr) {
+ ElfW(Addr) soaddr = reinterpret_cast<ElfW(Addr)>(addr) - load_bias;
+
+ for (size_t i = 0; i < gnu_nbucket_; ++i) {
+ uint32_t n = gnu_bucket_[i];
+
+ if (n == 0) {
+ continue;
+ }
+
+ do {
+ ElfW(Sym)* sym = symtab_ + n;
+ if (symbol_matches_soaddr(sym, soaddr)) {
+ return sym;
+ }
+ } while ((gnu_chain_[n++] & 1) == 0);
+ }
+
+ return nullptr;
+}
+
+ElfW(Sym)* soinfo::elf_addr_lookup(const void* addr) {
+ ElfW(Addr) soaddr = reinterpret_cast<ElfW(Addr)>(addr) - load_bias;
+
+ // Search the library's symbol table for any defined symbol which
+ // contains this address.
+ for (size_t i = 0; i < nchain_; ++i) {
+ ElfW(Sym)* sym = symtab_ + i;
+ if (symbol_matches_soaddr(sym, soaddr)) {
+ return sym;
+ }
+ }
+
+ return nullptr;
+}
+
+static void call_function(const char* function_name,
+ linker_ctor_function_t function,
+ const char* realpath) {
+ (void)realpath;
+ if (function == nullptr || reinterpret_cast<uintptr_t>(function) == static_cast<uintptr_t>(-1)) {
+ return;
+ }
+
+ TRACE("[ Calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ function(g_argc, g_argv, g_envp);
+ TRACE("[ Done calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
+}
+
+static void call_function(const char* function_name,
+ linker_dtor_function_t function,
+ const char* realpath) {
+ (void)function_name;
+ (void)realpath;
+ if (function == nullptr || reinterpret_cast<uintptr_t>(function) == static_cast<uintptr_t>(-1)) {
+ return;
+ }
+
+ TRACE("[ Calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ function();
+ TRACE("[ Done calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
+}
+
+template <typename F>
+static void call_array(const char* array_name,
+ F* functions,
+ size_t count,
+ bool reverse,
+ const char* realpath) {
+ if (functions == nullptr) {
+ return;
+ }
+
+ TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, realpath);
+
+ int begin = reverse ? (count - 1) : 0;
+ int end = reverse ? -1 : count;
+ int step = reverse ? -1 : 1;
+
+ for (int i = begin; i != end; i += step) {
+ TRACE("[ %s[%d] == %p ]", array_name, i, functions[i]);
+ call_function("function", functions[i], realpath);
+ }
+
+ TRACE("[ Done calling %s for '%s' ]", array_name, realpath);
+}
+
+void soinfo::call_pre_init_constructors() {
+ // DT_PREINIT_ARRAY functions are called before any other constructors for executables,
+ // but ignored in a shared library.
+ call_array("DT_PREINIT_ARRAY", preinit_array_, preinit_array_count_, false, get_realpath());
+}
+
+// Defined somewhere else in this linker.
+extern "C" void* android_dlsym(void* handle, const char* symbol);
+
+void (*bionic___system_properties_init)(void) = NULL;
+
+void soinfo::call_constructors() {
+ if (constructors_called) {
+ return;
+ }
+
+ if (soname_ != nullptr && strcmp(soname_, "libc.so") == 0) {
+ DEBUG("HYBRIS: =============> Skipping libc.so (but initializing properties)\n");
+ bionic___system_properties_init = (void(*)())android_dlsym(this, "__system_properties_init");
+ if (!bionic___system_properties_init) {
+ fprintf(stderr, "Could not initialize android system properties!\n");
+ abort();
+ }
+ bionic___system_properties_init();
+ constructors_called = true;
+ return;
+ }
+
+ // We set constructors_called before actually calling the constructors, otherwise it doesn't
+ // protect against recursive constructor calls. One simple example of constructor recursion
+ // is the libc debug malloc, which is implemented in libc_malloc_debug_leak.so:
+ // 1. The program depends on libc, so libc's constructor is called here.
+ // 2. The libc constructor calls dlopen() to load libc_malloc_debug_leak.so.
+ // 3. dlopen() calls the constructors on the newly created
+ // soinfo for libc_malloc_debug_leak.so.
+ // 4. The debug .so depends on libc, so CallConstructors is
+ // called again with the libc soinfo. If it doesn't trigger the early-
+ // out above, the libc constructor will be called again (recursively!).
+ constructors_called = true;
+
+ if (!is_main_executable() && preinit_array_ != nullptr) {
+ // The GNU dynamic linker silently ignores these, but we warn the developer.
+ PRINT("\"%s\": ignoring DT_PREINIT_ARRAY in shared library!", get_realpath());
+ }
+
+ get_children().for_each([] (soinfo* si) {
+ si->call_constructors();
+ });
+
+ if (!is_linker()) {
+ bionic_trace_begin((std::string("calling constructors: ") + get_realpath()).c_str());
+ }
+
+ // DT_INIT should be called before DT_INIT_ARRAY if both are present.
+ call_function("DT_INIT", init_func_, get_realpath());
+ call_array("DT_INIT_ARRAY", init_array_, init_array_count_, false, get_realpath());
+
+ if (!is_linker()) {
+ bionic_trace_end();
+ }
+}
+
+void soinfo::call_destructors() {
+ if (!constructors_called || (soname_ != nullptr && (strcmp(soname_, "libc.so") == 0))) {
+ return;
+ }
+
+ ScopedTrace trace((std::string("calling destructors: ") + get_realpath()).c_str());
+
+ // DT_FINI_ARRAY must be parsed in reverse order.
+ call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true, get_realpath());
+
+ // DT_FINI should be called after DT_FINI_ARRAY if both are present.
+ call_function("DT_FINI", fini_func_, get_realpath());
+}
+
+void soinfo::add_child(soinfo* child) {
+ if (has_min_version(0)) {
+ child->parents_.push_back(this);
+ this->children_.push_back(child);
+ }
+}
+
+void soinfo::remove_all_links() {
+ if (!has_min_version(0)) {
+ return;
+ }
+
+ // 1. Untie connected soinfos from 'this'.
+ children_.for_each([&] (soinfo* child) {
+ child->parents_.remove_if([&] (const soinfo* parent) {
+ return parent == this;
+ });
+ });
+
+ parents_.for_each([&] (soinfo* parent) {
+ parent->children_.remove_if([&] (const soinfo* child) {
+ return child == this;
+ });
+ });
+
+ // 2. Remove from the primary namespace
+ primary_namespace_->remove_soinfo(this);
+ primary_namespace_ = nullptr;
+
+ // 3. Remove from secondary namespaces
+ secondary_namespaces_.for_each([&](android_namespace_t* ns) {
+ ns->remove_soinfo(this);
+ });
+
+
+ // 4. Once everything untied - clear local lists.
+ parents_.clear();
+ children_.clear();
+ secondary_namespaces_.clear();
+}
+
+dev_t soinfo::get_st_dev() const {
+ if (has_min_version(0)) {
+ return st_dev_;
+ }
+
+ return 0;
+};
+
+ino_t soinfo::get_st_ino() const {
+ if (has_min_version(0)) {
+ return st_ino_;
+ }
+
+ return 0;
+}
+
+off64_t soinfo::get_file_offset() const {
+ if (has_min_version(1)) {
+ return file_offset_;
+ }
+
+ return 0;
+}
+
+uint32_t soinfo::get_rtld_flags() const {
+ if (has_min_version(1)) {
+ return rtld_flags_;
+ }
+
+ return 0;
+}
+
+uint32_t soinfo::get_dt_flags_1() const {
+ if (has_min_version(1)) {
+ return dt_flags_1_;
+ }
+
+ return 0;
+}
+
+void soinfo::set_dt_flags_1(uint32_t dt_flags_1) {
+ if (has_min_version(1)) {
+ if ((dt_flags_1 & DF_1_GLOBAL) != 0) {
+ rtld_flags_ |= RTLD_GLOBAL;
+ }
+
+ if ((dt_flags_1 & DF_1_NODELETE) != 0) {
+ rtld_flags_ |= RTLD_NODELETE;
+ }
+
+ dt_flags_1_ = dt_flags_1;
+ }
+}
+
+void soinfo::set_nodelete() {
+ rtld_flags_ |= RTLD_NODELETE;
+}
+
+const char* soinfo::get_realpath() const {
+#if defined(__work_around_b_24465209__)
+ if (has_min_version(2)) {
+ return realpath_.c_str();
+ } else {
+ return old_name_;
+ }
+#else
+ return realpath_.c_str();
+#endif
+}
+
+void soinfo::set_soname(const char* soname) {
+#if defined(__work_around_b_24465209__)
+ if (has_min_version(2)) {
+ soname_ = soname;
+ }
+ strlcpy(old_name_, soname_, sizeof(old_name_));
+#else
+ soname_ = soname;
+#endif
+}
+
+const char* soinfo::get_soname() const {
+#if defined(__work_around_b_24465209__)
+ if (has_min_version(2)) {
+ return soname_;
+ } else {
+ return old_name_;
+ }
+#else
+ return soname_;
+#endif
+}
+
+// This is a return on get_children()/get_parents() if
+// 'this->flags' does not have FLAG_NEW_SOINFO set.
+static soinfo_list_t g_empty_list;
+
+soinfo_list_t& soinfo::get_children() {
+ if (has_min_version(0)) {
+ return children_;
+ }
+
+ return g_empty_list;
+}
+
+const soinfo_list_t& soinfo::get_children() const {
+ if (has_min_version(0)) {
+ return children_;
+ }
+
+ return g_empty_list;
+}
+
+soinfo_list_t& soinfo::get_parents() {
+ if (has_min_version(0)) {
+ return parents_;
+ }
+
+ return g_empty_list;
+}
+
+static std::vector<std::string> g_empty_runpath;
+
+const std::vector<std::string>& soinfo::get_dt_runpath() const {
+ if (has_min_version(3)) {
+ return dt_runpath_;
+ }
+
+ return g_empty_runpath;
+}
+
+android_namespace_t* soinfo::get_primary_namespace() {
+ if (has_min_version(3)) {
+ return primary_namespace_;
+ }
+
+ return g_default_namespace;
+}
+
+void soinfo::add_secondary_namespace(android_namespace_t* secondary_ns) {
+ CHECK(has_min_version(3));
+ secondary_namespaces_.push_back(secondary_ns);
+}
+
+android_namespace_list_t& soinfo::get_secondary_namespaces() {
+ CHECK(has_min_version(3));
+ return secondary_namespaces_;
+}
+
+ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
+ if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
+ return call_ifunc_resolver(s->st_value + load_bias);
+ }
+
+ return static_cast<ElfW(Addr)>(s->st_value + load_bias);
+}
+
+const char* soinfo::get_string(ElfW(Word) index) const {
+ if (has_min_version(1) && (index >= strtab_size_)) {
+ async_safe_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d",
+ get_realpath(), strtab_size_, index);
+ }
+
+ return strtab_ + index;
+}
+
+bool soinfo::is_gnu_hash() const {
+ return (flags_ & FLAG_GNU_HASH) != 0;
+}
+
+bool soinfo::can_unload() const {
+ return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
+}
+
+bool soinfo::is_linked() const {
+ return (flags_ & FLAG_LINKED) != 0;
+}
+
+bool soinfo::is_main_executable() const {
+ return (flags_ & FLAG_EXE) != 0;
+}
+
+bool soinfo::is_linker() const {
+ return (flags_ & FLAG_LINKER) != 0;
+}
+
+void soinfo::set_linked() {
+ flags_ |= FLAG_LINKED;
+}
+
+void soinfo::set_linker_flag() {
+ flags_ |= FLAG_LINKER;
+}
+
+void soinfo::set_main_executable() {
+ flags_ |= FLAG_EXE;
+}
+
+void soinfo::increment_ref_count() {
+ local_group_root_->ref_count_++;
+}
+
+size_t soinfo::decrement_ref_count() {
+ return --local_group_root_->ref_count_;
+}
+
+soinfo* soinfo::get_local_group_root() const {
+ return local_group_root_;
+}
+
+void soinfo::set_mapped_by_caller(bool mapped_by_caller) {
+ if (mapped_by_caller) {
+ flags_ |= FLAG_MAPPED_BY_CALLER;
+ } else {
+ flags_ &= ~FLAG_MAPPED_BY_CALLER;
+ }
+}
+
+bool soinfo::is_mapped_by_caller() const {
+ return (flags_ & FLAG_MAPPED_BY_CALLER) != 0;
+}
+
+// This function returns api-level at the time of
+// dlopen/load. Note that libraries opened by system
+// will always have 'current' api level.
+uint32_t soinfo::get_target_sdk_version() const {
+ if (!has_min_version(2)) {
+ return __ANDROID_API__;
+ }
+
+ return local_group_root_->target_sdk_version_;
+}
+
+uintptr_t soinfo::get_handle() const {
+ CHECK(has_min_version(3));
+ CHECK(handle_ != 0);
+ return handle_;
+}
+
+void* soinfo::to_handle() {
+ if (get_application_target_sdk_version() < __ANDROID_API_N__ || !has_min_version(3)) {
+ return this;
+ }
+
+ return reinterpret_cast<void*>(get_handle());
+}
+
+void soinfo::generate_handle() {
+ CHECK(has_min_version(3));
+ CHECK(handle_ == 0); // Make sure this is the first call
+
+ // Make sure the handle is unique and does not collide
+ // with special values which are RTLD_DEFAULT and RTLD_NEXT.
+ do {
+ handle_ = rand();
+ //arc4random_buf(&handle_, sizeof(handle_));
+ // the least significant bit for the handle is always 1
+ // making it easy to test the type of handle passed to
+ // dl* functions.
+ handle_ = handle_ | 1;
+ } while (handle_ == reinterpret_cast<uintptr_t>(RTLD_DEFAULT) ||
+ handle_ == reinterpret_cast<uintptr_t>(RTLD_NEXT) ||
+ g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());
+
+ g_soinfo_handles_map[handle_] = this;
+}
+
+// TODO(dimitry): Move SymbolName methods to a separate file.
+
+uint32_t calculate_elf_hash(const char* name) {
+ const uint8_t* name_bytes = reinterpret_cast<const uint8_t*>(name);
+ uint32_t h = 0, g;
+
+ while (*name_bytes) {
+ h = (h << 4) + *name_bytes++;
+ g = h & 0xf0000000;
+ h ^= g;
+ h ^= g >> 24;
+ }
+
+ return h;
+}
+
+uint32_t SymbolName::elf_hash() {
+ if (!has_elf_hash_) {
+ elf_hash_ = calculate_elf_hash(name_);
+ has_elf_hash_ = true;
+ }
+
+ return elf_hash_;
+}
+
+uint32_t SymbolName::gnu_hash() {
+ if (!has_gnu_hash_) {
+ uint32_t h = 5381;
+ const uint8_t* name = reinterpret_cast<const uint8_t*>(name_);
+ while (*name != 0) {
+ h += (h << 5) + *name++; // h*33 + c = h + h * 32 + c = h + h << 5 + c
+ }
+
+ gnu_hash_ = h;
+ has_gnu_hash_ = true;
+ }
+
+ return gnu_hash_;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_soinfo.h
^
|
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_SOINFO_H
+#define __LINKER_SOINFO_H
+
+#include <link.h>
+
+#include <string>
+
+#include "linker_namespaces.h"
+
+#define FLAG_LINKED 0x00000001
+#define FLAG_EXE 0x00000004 // The main executable
+#define FLAG_LINKER 0x00000010 // The linker itself
+#define FLAG_GNU_HASH 0x00000040 // uses gnu hash
+#define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller
+ // and should not be unmapped
+#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
+
+#define SOINFO_VERSION 3
+
+typedef void (*linker_dtor_function_t)();
+typedef void (*linker_ctor_function_t)(int, char**, char**);
+
+class SymbolName {
+ public:
+ explicit SymbolName(const char* name)
+ : name_(name), has_elf_hash_(false), has_gnu_hash_(false),
+ elf_hash_(0), gnu_hash_(0) { }
+
+ const char* get_name() {
+ return name_;
+ }
+
+ uint32_t elf_hash();
+ uint32_t gnu_hash();
+
+ private:
+ const char* name_;
+ bool has_elf_hash_;
+ bool has_gnu_hash_;
+ uint32_t elf_hash_;
+ uint32_t gnu_hash_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
+};
+
+struct version_info {
+ constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
+
+ uint32_t elf_hash;
+ const char* name;
+ const soinfo* target_si;
+};
+
+// TODO(dimitry): remove reference from soinfo member functions to this class.
+class VersionTracker;
+
+#if defined(__work_around_b_24465209__)
+#define SOINFO_NAME_LEN 128
+#endif
+
+struct soinfo {
+#if defined(__work_around_b_24465209__)
+ private:
+ char old_name_[SOINFO_NAME_LEN];
+#endif
+ public:
+ const ElfW(Phdr)* phdr;
+ size_t phnum;
+#if defined(__work_around_b_24465209__)
+ ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility.
+#endif
+ ElfW(Addr) base;
+ size_t size;
+
+#if defined(__work_around_b_24465209__)
+ uint32_t unused1; // DO NOT USE, maintained for compatibility.
+#endif
+
+ ElfW(Dyn)* dynamic;
+
+#if defined(__work_around_b_24465209__)
+ uint32_t unused2; // DO NOT USE, maintained for compatibility
+ uint32_t unused3; // DO NOT USE, maintained for compatibility
+#endif
+
+ soinfo* next;
+ private:
+ uint32_t flags_;
+
+ const char* strtab_;
+ ElfW(Sym)* symtab_;
+
+ size_t nbucket_;
+ size_t nchain_;
+ uint32_t* bucket_;
+ uint32_t* chain_;
+
+#if defined(__mips__) || !defined(__LP64__)
+ // This is only used by mips and mips64, but needs to be here for
+ // all 32-bit architectures to preserve binary compatibility.
+ ElfW(Addr)** plt_got_;
+#endif
+
+#if defined(USE_RELA)
+ ElfW(Rela)* plt_rela_;
+ size_t plt_rela_count_;
+
+ ElfW(Rela)* rela_;
+ size_t rela_count_;
+#else
+ ElfW(Rel)* plt_rel_;
+ size_t plt_rel_count_;
+
+ ElfW(Rel)* rel_;
+ size_t rel_count_;
+#endif
+
+ linker_ctor_function_t* preinit_array_;
+ size_t preinit_array_count_;
+
+ linker_ctor_function_t* init_array_;
+ size_t init_array_count_;
+ linker_dtor_function_t* fini_array_;
+ size_t fini_array_count_;
+
+ linker_ctor_function_t init_func_;
+ linker_dtor_function_t fini_func_;
+
+#if defined(__arm__)
+ public:
+ // ARM EABI section used for stack unwinding.
+ uint32_t* ARM_exidx;
+ size_t ARM_exidx_count;
+ private:
+#elif defined(__mips__)
+ uint32_t mips_symtabno_;
+ uint32_t mips_local_gotno_;
+ uint32_t mips_gotsym_;
+ bool mips_relocate_got(const VersionTracker& version_tracker,
+ const soinfo_list_t& global_group,
+ const soinfo_list_t& local_group);
+#if !defined(__LP64__)
+ bool mips_check_and_adjust_fp_modes();
+#endif
+#endif
+ size_t ref_count_;
+ public:
+ link_map link_map_head;
+
+ bool constructors_called;
+
+ // When you read a virtual address from the ELF file, add this
+ // value to get the corresponding address in the process' address space.
+ ElfW(Addr) load_bias;
+
+#if !defined(__LP64__)
+ bool has_text_relocations;
+#endif
+ bool has_DT_SYMBOLIC;
+
+ public:
+ soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
+ off64_t file_offset, int rtld_flags);
+ ~soinfo();
+
+ void call_constructors();
+ void call_destructors();
+ void call_pre_init_constructors();
+ bool prelink_image();
+ bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
+ const android_dlextinfo* extinfo);
+ bool protect_relro();
+
+ void add_child(soinfo* child);
+ void remove_all_links();
+
+ ino_t get_st_ino() const;
+ dev_t get_st_dev() const;
+ off64_t get_file_offset() const;
+
+ uint32_t get_rtld_flags() const;
+ uint32_t get_dt_flags_1() const;
+ void set_dt_flags_1(uint32_t dt_flags_1);
+
+ soinfo_list_t& get_children();
+ const soinfo_list_t& get_children() const;
+
+ soinfo_list_t& get_parents();
+
+ bool find_symbol_by_name(SymbolName& symbol_name,
+ const version_info* vi,
+ const ElfW(Sym)** symbol) const;
+
+ ElfW(Sym)* find_symbol_by_address(const void* addr);
+ ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;
+
+ const char* get_string(ElfW(Word) index) const;
+ bool can_unload() const;
+ bool is_gnu_hash() const;
+
+ bool inline has_min_version(uint32_t min_version) const {
+#if defined(__work_around_b_24465209__)
+ (void) min_version;
+ return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
+#else
+ return true;
+#endif
+ }
+
+ bool is_linked() const;
+ bool is_linker() const;
+ bool is_main_executable() const;
+
+ void set_linked();
+ void set_linker_flag();
+ void set_main_executable();
+ void set_nodelete();
+
+ void increment_ref_count();
+ size_t decrement_ref_count();
+
+ soinfo* get_local_group_root() const;
+
+ void set_soname(const char* soname);
+ const char* get_soname() const;
+ const char* get_realpath() const;
+ const ElfW(Versym)* get_versym(size_t n) const;
+ ElfW(Addr) get_verneed_ptr() const;
+ size_t get_verneed_cnt() const;
+ ElfW(Addr) get_verdef_ptr() const;
+ size_t get_verdef_cnt() const;
+
+ uint32_t get_target_sdk_version() const;
+
+ void set_dt_runpath(const char *);
+ const std::vector<std::string>& get_dt_runpath() const;
+ android_namespace_t* get_primary_namespace();
+ void add_secondary_namespace(android_namespace_t* secondary_ns);
+ android_namespace_list_t& get_secondary_namespaces();
+
+ void set_mapped_by_caller(bool reserved_map);
+ bool is_mapped_by_caller() const;
+
+ uintptr_t get_handle() const;
+ void generate_handle();
+ void* to_handle();
+
+ private:
+ bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
+ ElfW(Sym)* elf_addr_lookup(const void* addr);
+ bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
+ ElfW(Sym)* gnu_addr_lookup(const void* addr);
+
+ bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
+ const char* sym_name, const version_info** vi);
+
+ template<typename ElfRelIteratorT>
+ bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
+ const soinfo_list_t& global_group, const soinfo_list_t& local_group);
+
+ private:
+ // This part of the structure is only available
+ // when FLAG_NEW_SOINFO is set in this->flags.
+ uint32_t version_;
+
+ // version >= 0
+ dev_t st_dev_;
+ ino_t st_ino_;
+
+ // dependency graph
+ soinfo_list_t children_;
+ soinfo_list_t parents_;
+
+ // version >= 1
+ off64_t file_offset_;
+ uint32_t rtld_flags_;
+ uint32_t dt_flags_1_;
+ size_t strtab_size_;
+
+ // version >= 2
+
+ size_t gnu_nbucket_;
+ uint32_t* gnu_bucket_;
+ uint32_t* gnu_chain_;
+ uint32_t gnu_maskwords_;
+ uint32_t gnu_shift2_;
+ ElfW(Addr)* gnu_bloom_filter_;
+
+ soinfo* local_group_root_;
+
+ uint8_t* android_relocs_;
+ size_t android_relocs_size_;
+
+ const char* soname_;
+ std::string realpath_;
+
+ const ElfW(Versym)* versym_;
+
+ ElfW(Addr) verdef_ptr_;
+ size_t verdef_cnt_;
+
+ ElfW(Addr) verneed_ptr_;
+ size_t verneed_cnt_;
+
+ uint32_t target_sdk_version_;
+
+ // version >= 3
+ std::vector<std::string> dt_runpath_;
+ android_namespace_t* primary_namespace_;
+ android_namespace_list_t secondary_namespaces_;
+ uintptr_t handle_;
+
+ friend soinfo* get_libdl_info(const char* linker_path, const link_map& linker_map);
+};
+
+// This function is used by dlvsym() to calculate hash of sym_ver
+uint32_t calculate_elf_hash(const char* name);
+
+const char* fix_dt_needed(const char* dt_needed, const char* sopath);
+
+template<typename F>
+void for_each_dt_needed(const soinfo* si, F action) {
+ for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
+ if (d->d_tag == DT_NEEDED) {
+ action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath()));
+ }
+ }
+}
+
+#endif /* __LINKER_SOINFO_H */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_utils.cpp
^
|
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_utils.h"
+
+#include "linker_debug.h"
+#include "linker_globals.h"
+
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <linux/limits.h>
+
+#include <algorithm>
+#include <sstream>
+
+#include "hybris_compat.h"
+
+std::string trim(const std::string& s) {
+ std::string result;
+
+ if (s.size() == 0) {
+ return result;
+ }
+
+ size_t start_index = 0;
+ size_t end_index = s.size() - 1;
+
+ // Skip initial whitespace.
+ while (start_index < s.size()) {
+ if (!isspace(s[start_index])) {
+ break;
+ }
+ start_index++;
+ }
+
+ // Skip terminating whitespace.
+ while (end_index >= start_index) {
+ if (!isspace(s[end_index])) {
+ break;
+ }
+ end_index--;
+ }
+
+ // All spaces, no beef.
+ if (end_index < start_index) {
+ return "";
+ }
+ // Start_index is the first non-space, end_index is the last one.
+ return s.substr(start_index, end_index - start_index + 1);
+}
+
+std::vector<std::string> split(const std::string &text, const std::string &sep) {
+ std::vector<std::string> tokens;
+ std::size_t start = 0, end = 0;
+ while ((end = text.find(sep, start)) != std::string::npos) {
+ tokens.push_back(text.substr(start, end - start));
+ start = end + 1;
+ }
+ tokens.push_back(text.substr(start));
+ return tokens;
+}
+
+std::string join(const std::vector<std::string>& things, char separator) {
+ if (things.empty()) {
+ return "";
+ }
+ std::ostringstream result;
+ result << *things.begin();
+ for (auto it = std::next(things.begin()); it != things.end(); ++it) {
+ result << separator << *it;
+ }
+ return result.str();
+}
+
+void format_string(std::string* str, const std::vector<std::pair<std::string, std::string>>& params) {
+ size_t pos = 0;
+ while (pos < str->size()) {
+ pos = str->find("$", pos);
+ if (pos == std::string::npos) break;
+ for (const auto& param : params) {
+ const std::string& token = param.first;
+ const std::string& replacement = param.second;
+ if (str->substr(pos + 1, token.size()) == token) {
+ str->replace(pos, token.size() + 1, replacement);
+ // -1 to compensate for the ++pos below.
+ pos += replacement.size() - 1;
+ break;
+ } else if (str->substr(pos + 1, token.size() + 2) == "{" + token + "}") {
+ str->replace(pos, token.size() + 3, replacement);
+ pos += replacement.size() - 1;
+ break;
+ }
+ }
+ // Skip $ in case it did not match any of the known substitutions.
+ ++pos;
+ }
+}
+
+std::string dirname(const char* path) {
+ const char* last_slash = strrchr(path, '/');
+
+ if (last_slash == path) {
+ return "/";
+ } else if (last_slash == nullptr) {
+ return ".";
+ } else {
+ return std::string(path, last_slash - path);
+ }
+}
+
+bool normalize_path(const char* path, std::string* normalized_path) {
+ // Input should be an absolute path
+ if (path[0] != '/') {
+ PRINT("normalize_path - invalid input: \"%s\", the input path should be absolute", path);
+ return false;
+ }
+
+ const size_t len = strlen(path) + 1;
+ char buf[len];
+
+ const char* in_ptr = path;
+ char* out_ptr = buf;
+
+ while (*in_ptr != 0) {
+ if (*in_ptr == '/') {
+ char c1 = in_ptr[1];
+ if (c1 == '.') {
+ char c2 = in_ptr[2];
+ if (c2 == '/') {
+ in_ptr += 2;
+ continue;
+ } else if (c2 == '.' && (in_ptr[3] == '/' || in_ptr[3] == 0)) {
+ in_ptr += 3;
+ while (out_ptr > buf && *--out_ptr != '/') {
+ }
+ if (in_ptr[0] == 0) {
+ // retain '/'
+ out_ptr++;
+ }
+ continue;
+ }
+ } else if (c1 == '/') {
+ ++in_ptr;
+ continue;
+ }
+ }
+ *out_ptr++ = *in_ptr++;
+ }
+
+ *out_ptr = 0;
+ *normalized_path = buf;
+ return true;
+}
+
+bool file_is_in_dir(const std::string& file, const std::string& dir) {
+ const char* needle = dir.c_str();
+ const char* haystack = file.c_str();
+ size_t needle_len = strlen(needle);
+
+ return strncmp(haystack, needle, needle_len) == 0 &&
+ haystack[needle_len] == '/' &&
+ strchr(haystack + needle_len + 1, '/') == nullptr;
+}
+
+bool file_is_under_dir(const std::string& file, const std::string& dir) {
+ const char* needle = dir.c_str();
+ const char* haystack = file.c_str();
+ size_t needle_len = strlen(needle);
+
+ return strncmp(haystack, needle, needle_len) == 0 &&
+ haystack[needle_len] == '/';
+}
+
+const char* const kZipFileSeparator = "!/";
+
+bool parse_zip_path(const char* input_path, std::string* zip_path, std::string* entry_path) {
+ std::string normalized_path;
+ if (!normalize_path(input_path, &normalized_path)) {
+ return false;
+ }
+
+ const char* const path = normalized_path.c_str();
+ TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
+
+ // Treat an '!/' separator inside a path as the separator between the name
+ // of the zip file on disk and the subdirectory to search within it.
+ // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
+ // "bar/bas/x.so" within "foo.zip".
+ const char* const separator = strstr(path, kZipFileSeparator);
+ if (separator == nullptr) {
+ return false;
+ }
+
+ char buf[512];
+ if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
+ PRINT("Warning: ignoring very long library path: %s", path);
+ return false;
+ }
+
+ buf[separator - path] = '\0';
+
+ *zip_path = buf;
+ *entry_path = &buf[separator - path + 2];
+
+ return true;
+}
+
+constexpr off64_t kPageMask = ~static_cast<off64_t>(PAGE_SIZE-1);
+
+off64_t page_start(off64_t offset) {
+ return offset & kPageMask;
+}
+
+bool safe_add(off64_t* out, off64_t a, size_t b) {
+ CHECK(a >= 0);
+ if (static_cast<uint64_t>(INT64_MAX - a) < b) {
+ return false;
+ }
+
+ *out = a + b;
+ return true;
+}
+
+size_t page_offset(off64_t offset) {
+ return static_cast<size_t>(offset & (PAGE_SIZE-1));
+}
+
+void split_path(const char* path, const char* delimiters,
+ std::vector<std::string>* paths) {
+ if (path != nullptr && path[0] != 0) {
+ *paths = split(path, delimiters);
+ }
+}
+
+void resolve_paths(std::vector<std::string>& paths,
+ std::vector<std::string>* resolved_paths) {
+ resolved_paths->clear();
+ for (const auto& path : paths) {
+ // skip empty paths
+ if (path.empty()) {
+ continue;
+ }
+
+ char resolved_path[PATH_MAX];
+ const char* original_path = path.c_str();
+ if (realpath(original_path, resolved_path) != nullptr) {
+ struct stat s;
+ if (stat(resolved_path, &s) == 0) {
+ if (S_ISDIR(s.st_mode)) {
+ resolved_paths->push_back(resolved_path);
+ } else {
+ DL_WARN("Warning: \"%s\" is not a directory (excluding from path)", resolved_path);
+ continue;
+ }
+ } else {
+ DL_WARN("Warning: cannot stat file \"%s\": %s", resolved_path, strerror(errno));
+ continue;
+ }
+ } else {
+ std::string zip_path;
+ std::string entry_path;
+
+ std::string normalized_path;
+
+ if (!normalize_path(original_path, &normalized_path)) {
+ DL_WARN("Warning: unable to normalize \"%s\"", original_path);
+ continue;
+ }
+
+ if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
+ if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
+ DL_WARN("Warning: unable to resolve \"%s\": %s", zip_path.c_str(), strerror(errno));
+ continue;
+ }
+
+ resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
+ }
+ }
+ }
+}
+
+void stringAppendV(std::string* dst, const char* format, va_list ap) {
+ // First try with a small fixed size buffer
+ char space[1024];
+
+ // It's possible for methods that use a va_list to invalidate
+ // the data in it upon use. The fix is to make a copy
+ // of the structure before using it and use that copy instead.
+ va_list backup_ap;
+ va_copy(backup_ap, ap);
+ int result = vsnprintf(space, sizeof(space), format, backup_ap);
+ va_end(backup_ap);
+
+ if (result < static_cast<int>(sizeof(space))) {
+ if (result >= 0) {
+ // Normal case -- everything fit.
+ dst->append(space, result);
+ return;
+ }
+
+ if (result < 0) {
+ // Just an error.
+ return;
+ }
+ }
+
+ // Increase the buffer size to the size requested by vsnprintf,
+ // plus one for the closing \0.
+ int length = result + 1;
+ char* buf = new char[length];
+
+ // Restore the va_list before we use it again
+ va_copy(backup_ap, ap);
+ result = vsnprintf(buf, length, format, backup_ap);
+ va_end(backup_ap);
+
+ if (result >= 0 && result < length) {
+ // It fit
+ dst->append(buf, result);
+ }
+ delete[] buf;
+}
+
+std::string stringPrintf(const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ std::string result;
+ stringAppendV(&result, fmt, ap);
+ va_end(ap);
+ return result;
+}
+
+void stringAppendF(std::string* dst, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ stringAppendV(dst, format, ap);
+ va_end(ap);
+}
+
+bool readFdToString(int fd, std::string* content) {
+ content->clear();
+
+ // Although original we had small files in mind, this code gets used for
+ // very large files too, where the std::string growth heuristics might not
+ // be suitable. https://code.google.com/p/android/issues/detail?id=258500.
+ struct stat sb;
+ if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
+ content->reserve(sb.st_size);
+ }
+
+ char buf[BUFSIZ];
+ ssize_t n;
+ while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+ content->append(buf, n);
+ }
+ return (n == 0) ? true : false;
+}
+
+bool readFileToString(const std::string& path, std::string* content, bool follow_symlinks) {
+ content->clear();
+
+ int flags = O_RDONLY | O_CLOEXEC | O_BINARY | (follow_symlinks ? 0 : O_NOFOLLOW);
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags)));
+ if (fd == -1) {
+ return false;
+ }
+ return readFdToString(fd, content);
+}
+
+bool startsWith(const std::string& s, const char* prefix) {
+ return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
+}
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/linker_utils.h
^
|
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __LINKER_UTILS_H
+#define __LINKER_UTILS_H
+
+#include <cstdarg>
+#include <string>
+#include <vector>
+
+extern const char* const kZipFileSeparator;
+
+std::string trim(const std::string& s);
+std::vector<std::string> split(const std::string &text, const std::string &sep);
+std::string join(const std::vector<std::string>& things, char separator);
+
+void format_string(std::string* str, const std::vector<std::pair<std::string, std::string>>& params);
+
+bool file_is_in_dir(const std::string& file, const std::string& dir);
+bool file_is_under_dir(const std::string& file, const std::string& dir);
+bool normalize_path(const char* path, std::string* normalized_path);
+bool parse_zip_path(const char* input_path, std::string* zip_path, std::string* entry_path);
+
+// For every path element this function checks of it exists, and is a directory,
+// and normalizes it:
+// 1. For regular path it converts it to realpath()
+// 2. For path in a zip file it uses realpath on the zipfile
+// normalizes entry name by calling normalize_path function.
+void resolve_paths(std::vector<std::string>& paths,
+ std::vector<std::string>* resolved_paths);
+
+void split_path(const char* path, const char* delimiters, std::vector<std::string>* paths);
+
+std::string dirname(const char* path);
+
+off64_t page_start(off64_t offset);
+size_t page_offset(off64_t offset);
+bool safe_add(off64_t* out, off64_t a, size_t b);
+
+void stringAppendV(std::string* dst, const char* format, va_list ap);
+std::string stringPrintf(const char* fmt, ...);
+void stringAppendF(std::string* dst, const char* format, ...);
+
+#define CHECK(predicate) \
+ do { \
+ if (!(predicate)) { \
+ fprintf(stderr, "%s:%d: %s CHECK '" #predicate "' failed", \
+ __FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while(0)
+
+bool readFileToString(const std::string& path, std::string* content, bool follow_symlinks = false);
+
+bool startsWith(const std::string& s, const char* prefix);
+
+#endif
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/common/o/rt.cpp
^
|
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This function is an empty stub where GDB locates a breakpoint to get notified
+ * about linker activity. It canʼt be inlined away, can't be hidden.
+ */
+extern "C" void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity() {
+}
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/configure.ac
^
|
@@ -60,11 +60,11 @@
[trace="no"])
AM_CONDITIONAL( [WANT_TRACE], [test x"$trace" = x"yes"])
-AC_ARG_ENABLE(mm_arm_tracing,
- [ --enable-mm-arm-tracing Enable ARM (32-bit only) tracing, useful for understanding what the blob is doing, currently only the mm linker is supported. (default=disabled)],
- [mm_arm_tracing=$enableval],
- [mm_arm_tracing="no"])
-AM_CONDITIONAL([WANT_ARM_TRACING], [test x"$mm_arm_tracing" = x"yes"])
+AC_ARG_ENABLE(arm_tracing,
+ [ --enable-arm-tracing Enable ARM (32-bit only) tracing, useful for understanding what the blob is doing, currently only the mm linker is supported. (default=disabled)],
+ [arm_tracing=$enableval],
+ [arm_tracing="no"])
+AM_CONDITIONAL([WANT_ARM_TRACING], [test x"$arm_tracing" = x"yes"])
AC_ARG_ENABLE(mesa,
[ --enable-mesa Enable mesa headers (default=disabled)],
@@ -72,6 +72,12 @@
[mesa="no"])
AM_CONDITIONAL( [WANT_MESA], [test x"$mesa" = x"yes"])
+AC_ARG_ENABLE(ubuntu-camera-headers,
+ [ --enable-ubuntu-camera-headers Enable Ubuntu camera headers (default=disabled)],
+ [ubuntu-camera-headers=$enableval],
+ [ubuntu-camera-headers="no"])
+AM_CONDITIONAL( [WANT_UBUNTU_CAMERA_HEADERS], [test x"$ubuntu-camera-headers" = x"yes"])
+
AC_ARG_ENABLE(wayland,
[ --enable-wayland Enable wayland support (default=disabled)],
[wayland=$enableval
@@ -151,12 +157,20 @@
[ --with-android-headers=DIR Use android headers available in DIR. See utils/extract-headers.sh ],
[
AM_CONDITIONAL([HAS_LIBNFC_NXP_HEADERS], [test -f $withval/libnfc-nxp/phLibNfc.h])
+ AM_CONDITIONAL([HAS_WIFI_LEGACY_HEADERS], [test -f $withval/hardware_legacy/wifi.h])
+ AM_CONDITIONAL([HAS_HWCOMPOSER2_HEADERS], [test -f $withval/hardware/hwcomposer2.h])
+ AM_CONDITIONAL([HAS_GRALLOC1_HEADER], [test -f $withval/hardware/gralloc1.h])
+ AM_CONDITIONAL([HAS_VIBRATOR_HEADER], [test -f $withval/hardware_legacy/vibrator.h])
AS_IF([test -f $withval/libnfc-nxp/phLibNfc.h], [ANDROID_HEADERS_CFLAGS="-I$withval -I$withval/libnfc-nxp"],[ANDROID_HEADERS_CFLAGS="-I$withval"])
AC_SUBST([ANDROID_HEADERS_CFLAGS])
],
[
PKG_CHECK_MODULES(ANDROID_HEADERS, android-headers,, exit)
AM_CONDITIONAL([HAS_LIBNFC_NXP_HEADERS], [false])
+ AM_CONDITIONAL([HAS_WIFI_LEGACY_HEADERS], [false])
+ AM_CONDITIONAL([HAS_HWCOMPOSER2_HEADERS], [false])
+ AM_CONDITIONAL([HAS_GRALLOC1_HEADER], [false])
+ AM_CONDITIONAL([HAS_VIBRATOR_HEADER], [false])
]
)
CPPFLAGS="$CPPFLAGS $ANDROID_HEADERS_CFLAGS"
@@ -214,6 +228,8 @@
AC_MSG_NOTICE("Android headers version is $android_headers_major.$android_headers_minor.$android_headers_patch")
# Add automake tests for version/API needs here that you need in code, including test .am's
+AM_CONDITIONAL([HAS_ANDROID_9_0_0], [test $android_headers_major -ge 9 -a $android_headers_minor -ge 0 ])
+AM_CONDITIONAL([HAS_ANDROID_8_0_0], [test $android_headers_major -ge 8 -a $android_headers_minor -ge 0 ])
AM_CONDITIONAL([HAS_ANDROID_7_0_0], [test $android_headers_major -ge 7 -a $android_headers_minor -ge 0 ])
AM_CONDITIONAL([HAS_ANDROID_6_0_0], [test $android_headers_major -ge 6 -a $android_headers_minor -ge 0 ])
AM_CONDITIONAL([HAS_ANDROID_5_0_0], [test $android_headers_major -ge 5 -a $android_headers_minor -ge 0 ])
@@ -246,6 +262,7 @@
common/stub/Makefile
common/mm/Makefile
common/n/Makefile
+ common/o/Makefile
egl/egl.pc
egl/Makefile
egl/platforms/Makefile
@@ -262,6 +279,8 @@
glesv2/Makefile
hardware/Makefile
hardware/libhardware.pc
+ gralloc/Makefile
+ gralloc/libgralloc.pc
libnfc_nxp/Makefile
libnfc_nxp/libnfc_nxp.pc
libnfc_ndef_nxp/Makefile
@@ -281,6 +300,8 @@
utils/Makefile
sf/Makefile
sf/libsf.pc
+ hwc2/Makefile
+ hwc2/libhwc2.pc
opencl/Makefile
opencl/OpenCL.pc
tests/Makefile
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/eglhybris.h
^
|
@@ -18,7 +18,6 @@
#ifndef EGL_HYBRIS_H_
#define EGL_HYBRIS_H_
-#include <hardware/gralloc.h>
/* Needed for ICS window.h */
#include <string.h>
#include <system/window.h>
@@ -27,8 +26,6 @@
extern "C" {
#endif
-int hybris_register_buffer_handle(buffer_handle_t handle);
-int hybris_unregister_buffer_handle(buffer_handle_t handle);
void hybris_dump_buffer_to_file(struct ANativeWindowBuffer *buf);
void *hybris_android_egl_dlsym(const char *symbol);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/eglplatformcommon.cpp
^
|
@@ -3,7 +3,6 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
-#include <hardware/gralloc.h>
#include <stdio.h>
#include <assert.h>
#include "config.h"
@@ -22,15 +21,13 @@
#include "windowbuffer.h"
+#include <hybris/gralloc/gralloc.h>
+
static struct ws_egl_interface *my_egl_interface;
-static gralloc_module_t *my_gralloc = 0;
-static alloc_device_t *my_alloc = 0;
-extern "C" void eglplatformcommon_init(struct ws_egl_interface *egl_iface, gralloc_module_t *gralloc, alloc_device_t *allocdevice)
+extern "C" void eglplatformcommon_init(struct ws_egl_interface *egl_iface)
{
my_egl_interface = egl_iface;
- my_gralloc = gralloc;
- my_alloc = allocdevice;
}
extern "C" void *hybris_android_egl_dlsym(const char *symbol)
@@ -48,33 +45,17 @@
return (*my_egl_interface->get_mapping)(surface);
}
-extern "C" int hybris_register_buffer_handle(buffer_handle_t handle)
-{
- if (!my_gralloc)
- return -1;
-
- return my_gralloc->registerBuffer(my_gralloc, handle);
-}
-
-extern "C" int hybris_unregister_buffer_handle(buffer_handle_t handle)
-{
- if (!my_gralloc)
- return -1;
-
- return my_gralloc->unregisterBuffer(my_gralloc, handle);
-}
-
extern "C" void hybris_dump_buffer_to_file(ANativeWindowBuffer *buf)
{
static int cnt = 0;
void *vaddr;
- int ret = my_gralloc->lock(my_gralloc, buf->handle, buf->usage, 0, 0, buf->width, buf->height, &vaddr);
+ int ret = hybris_gralloc_lock(buf->handle, buf->usage, 0, 0, buf->width, buf->height, &vaddr);
TRACE("buf:%p gralloc lock returns %i", buf, ret);
TRACE("buf:%p lock to vaddr %p", buf, vaddr);
char b[1024];
int bytes_pp = 0;
- if (buf->format == HAL_PIXEL_FORMAT_RGBA_8888)
+ if (buf->format == HAL_PIXEL_FORMAT_RGBA_8888 || buf->format == HAL_PIXEL_FORMAT_BGRA_8888)
bytes_pp = 4;
else if (buf->format == HAL_PIXEL_FORMAT_RGB_565)
bytes_pp = 2;
@@ -87,15 +68,14 @@
::write(fd, vaddr, buf->stride * buf->height * bytes_pp);
::close(fd);
- my_gralloc->unlock(my_gralloc, buf->handle);
+ hybris_gralloc_unlock(buf->handle);
}
#ifdef WANT_WAYLAND
extern "C" EGLBoolean eglplatformcommon_eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
- assert(my_gralloc != NULL);
- server_wlegl_create(display, my_gralloc, my_alloc);
+ server_wlegl_create(display);
return EGL_TRUE;
}
@@ -116,6 +96,7 @@
*value = EGL_TEXTURE_RGB;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
*value = EGL_TEXTURE_RGBA;
break;
default:
@@ -182,17 +163,15 @@
extern "C" EGLBoolean eglplatformcommon_eglHybrisCreateRemoteBuffer(EGLint width, EGLint height, EGLint usage, EGLint format, EGLint stride,
int num_ints, int *ints, int num_fds, int *fds, EGLClientBuffer *buffer)
{
- assert(my_gralloc != NULL);
-
native_handle_t *native = native_handle_create(num_fds, num_ints);
memcpy(&native->data[0], fds, num_fds * sizeof(int));
memcpy(&native->data[num_fds], ints, num_ints * sizeof(int));
- int ret = my_gralloc->registerBuffer(my_gralloc, (buffer_handle_t)native);
+ int ret = hybris_gralloc_retain(native);
if (ret == 0)
{
- RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, stride, format, usage, (buffer_handle_t)native, my_gralloc, my_alloc);
+ RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, stride, format, usage, (buffer_handle_t)native);
buf->common.incRef(&buf->common);
*buffer = (EGLClientBuffer) static_cast<ANativeWindowBuffer *>(buf);
return EGL_TRUE;
@@ -207,14 +186,11 @@
buffer_handle_t _handle;
int _stride;
- assert(my_gralloc != NULL);
- assert(my_alloc != NULL);
-
- ret = my_alloc->alloc(my_alloc, width, height, format, usage, &_handle, &_stride);
+ hybris_gralloc_allocate(width, height, format, usage, &_handle, (uint32_t*)&_stride);
if (ret == 0)
{
- RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, _stride, format, usage, _handle, my_gralloc, my_alloc);
+ RemoteWindowBuffer *buf = new RemoteWindowBuffer(width, height, _stride, format, usage, _handle);
buf->common.incRef(&buf->common);
buf->setAllocated(true);
*buffer = (EGLClientBuffer) static_cast<ANativeWindowBuffer *>(buf);
@@ -230,9 +206,7 @@
int ret;
RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
- assert(my_gralloc != NULL);
-
- ret = my_gralloc->lock(my_gralloc, buf->handle, usage, l, t, w, h, vaddr);
+ ret = hybris_gralloc_lock(buf->handle, usage, l, t, w, h, vaddr);
if (ret == 0)
return EGL_TRUE;
else
@@ -244,9 +218,7 @@
int ret;
RemoteWindowBuffer *buf = static_cast<RemoteWindowBuffer *>((ANativeWindowBuffer *) buffer);
- assert(my_gralloc != NULL);
-
- ret = my_gralloc->unlock(my_gralloc, buf->handle);
+ ret = hybris_gralloc_unlock(buf->handle);
if (ret == 0)
return EGL_TRUE;
else
@@ -363,8 +335,8 @@
if (name == EGL_EXTENSIONS)
{
const char *ret = (*real_eglQueryString)(dpy, name);
- static char eglextensionsbuf[1024];
- snprintf(eglextensionsbuf, 1022, "%sEGL_HYBRIS_native_buffer2 EGL_HYBRIS_WL_acquire_native_buffer %s", ret ? ret : "",
+ static char eglextensionsbuf[2048];
+ snprintf(eglextensionsbuf, 2046, "%sEGL_HYBRIS_native_buffer2 EGL_HYBRIS_WL_acquire_native_buffer %s", ret ? ret : "",
#ifdef WANT_WAYLAND
"EGL_WL_bind_wayland_display "
#else
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/eglplatformcommon.h
^
|
@@ -1,10 +1,9 @@
#ifndef __EGLPLATFORMCOMMON_H
#define __EGLPLATFORMCOMMON_H
#include <string.h>
-#include <hardware/gralloc.h>
#include <EGL/egl.h>
-void eglplatformcommon_init(struct ws_egl_interface *egl_iface, gralloc_module_t *gralloc, alloc_device_t *allocdevice);
+void eglplatformcommon_init(struct ws_egl_interface *egl_iface);
__eglMustCastToProperFunctionPointerType eglplatformcommon_eglGetProcAddress(const char *procname);
void eglplatformcommon_passthroughImageKHR(EGLContext *ctx, EGLenum *target, EGLClientBuffer *buffer, const EGLint **attrib_list);
const char *eglplatformcommon_eglQueryString(EGLDisplay dpy, EGLint name, const char *(*real_eglQueryString)(EGLDisplay dpy, EGLint name));
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/nativewindowbase.cpp
^
|
@@ -1,4 +1,11 @@
+
+#ifndef ANDROID_BUILD
#include <android-config.h>
+#include "logging.h"
+#else
+#define TRACE(message, ...)
+#endif
+
#include <string.h>
#include <system/window.h>
#include <system/graphics.h>
@@ -12,15 +19,14 @@
}
#endif
+#ifdef ANDROID_BUILD
+#define TRACE(...)
+#define HYBRIS_TRACE_BEGIN(...)
+#define HYBRIS_TRACE_END(...)
+#endif
#include "nativewindowbase.h"
-#include "logging.h"
-
-#define TRACE(message, ...) HYBRIS_DEBUG_LOG(EGL, message, ##__VA_ARGS__)
-
-
-
BaseNativeWindowBuffer::BaseNativeWindowBuffer()
{
TRACE("%p", this);
@@ -265,6 +271,10 @@
case NATIVE_WINDOW_DEFAULT_DATASPACE: return "NATIVE_WINDOW_DEFAULT_DATASPACE";
case NATIVE_WINDOW_CONSUMER_USAGE_BITS: return "NATIVE_WINDOW_CONSUMER_USAGE_BITS";
#endif
+#if ANDROID_VERSION_MAJOR>=8
+ case NATIVE_WINDOW_IS_VALID: return "NATIVE_WINDOW_IS_VALID";
+ case NATIVE_WINDOW_BUFFER_AGE: return "NATIVE_WINDOW_BUFFER_AGE";
+#endif
default: return "NATIVE_UNKNOWN_QUERY";
}
}
@@ -309,6 +319,16 @@
*value = self->getUsage();
return NO_ERROR;
#endif
+#if ANDROID_VERSION_MAJOR>=8
+ case NATIVE_WINDOW_IS_VALID:
+ // sure :)
+ *value = 1;
+ return NO_ERROR;
+ case NATIVE_WINDOW_BUFFER_AGE:
+ // sure :)
+ *value = 2;
+ return NO_ERROR;
+#endif
}
TRACE("EGL error: unkown window attribute! %i", what);
*value = 0;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/server_wlegl.cpp
^
|
@@ -28,15 +28,18 @@
extern "C" {
#include <cutils/native_handle.h>
-#include <hardware/gralloc.h>
}
+#include "logging.h"
+
#include <wayland-server.h>
#include "wayland-android-server-protocol.h"
#include "server_wlegl_private.h"
#include "server_wlegl_handle.h"
#include "server_wlegl_buffer.h"
+#include <hybris/gralloc/gralloc.h>
+
static inline server_wlegl *
server_wlegl_from(struct wl_resource *resource)
{
@@ -127,7 +130,10 @@
usage |= GRALLOC_USAGE_HW_COMPOSER;
- int ret = wlegl->alloc->alloc(wlegl->alloc, width, height, format, usage, &_handle, &_stride);
+ int r = hybris_gralloc_allocate(width, height, format, usage, &_handle, (uint32_t*)&_stride);
+ if (r) {
+ HYBRIS_ERROR_LOG(SERVER_WLEGL, "failed to allocate buffer\n");
+ }
server_wlegl_buffer *buffer = server_wlegl_buffer_create_server(client, width, height, _stride, format, usage, _handle, wlegl);
struct wl_array ints;
@@ -165,18 +171,15 @@
}
server_wlegl *
-server_wlegl_create(struct wl_display *display, gralloc_module_t *gralloc, alloc_device_t *alloc)
+server_wlegl_create(struct wl_display *display)
{
struct server_wlegl *wlegl;
- int ret;
wlegl = new server_wlegl;
wlegl->display = display;
wlegl->global = wl_global_create(display, &android_wlegl_interface, 2,
wlegl, server_wlegl_bind);
- wlegl->gralloc = (const gralloc_module_t *)gralloc;
- wlegl->alloc = alloc;
return wlegl;
}
@@ -186,8 +189,6 @@
{
/* FIXME: server_wlegl_buffer objects may exist */
- /* no way to release wlegl->gralloc */
-
/* FIXME: remove global_ */
/* Better to leak than expose dtor segfaults, the server
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/server_wlegl.h
^
|
@@ -25,8 +25,8 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <hardware/gralloc.h>
#include <system/window.h>
+
extern "C" {
struct wl_display;
@@ -37,7 +37,7 @@
struct server_wlegl;
server_wlegl *
-server_wlegl_create(struct wl_display *wldpy, gralloc_module_t *gralloc, alloc_device_t *alloc);
+server_wlegl_create(struct wl_display *wldpy);
void
server_wlegl_destroy(server_wlegl *wlegl);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/server_wlegl_buffer.cpp
^
|
@@ -27,6 +27,8 @@
#include "server_wlegl_buffer.h"
#include "server_wlegl_private.h"
+#include <hybris/gralloc/gralloc.h>
+
static void
destroy(struct wl_client *client, struct wl_resource *resource)
{
@@ -69,14 +71,14 @@
buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
wl_resource_set_implementation(buffer->resource, &server_wlegl_buffer_impl, buffer, server_wlegl_buffer_dtor);
- ret = wlegl->gralloc->registerBuffer(wlegl->gralloc, handle);
+ ret = hybris_gralloc_retain(handle);
if (ret) {
delete buffer;
return NULL;
}
buffer->buf = new RemoteWindowBuffer(
- width, height, stride, format, usage, handle, wlegl->gralloc, NULL);
+ width, height, stride, format, usage, handle);
buffer->buf->common.incRef(&buffer->buf->common);
return buffer;
}
@@ -92,14 +94,13 @@
server_wlegl *wlegl)
{
server_wlegl_buffer *buffer = new server_wlegl_buffer;
- int ret;
buffer->wlegl = wlegl;
buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, 0);
wl_resource_set_implementation(buffer->resource, &server_wlegl_buffer_impl, buffer, server_wlegl_buffer_dtor);
buffer->buf = new RemoteWindowBuffer(
- width, height, stride, format, usage, handle, wlegl->gralloc, wlegl->alloc);
+ width, height, stride, format, usage, handle);
buffer->buf->setAllocated(true);
buffer->buf->common.incRef(&buffer->buf->common);
return buffer;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/server_wlegl_private.h
^
|
@@ -23,7 +23,6 @@
#ifndef SERVER_WLEGL_PRIVATE_H
#define SERVER_WLEGL_PRIVATE_H
-#include <hardware/gralloc.h>
#include <wayland-server.h>
#include "server_wlegl.h"
@@ -32,9 +31,6 @@
struct wl_display *display;
struct wl_global *global;
-
- const gralloc_module_t *gralloc;
- alloc_device_t *alloc;
};
#endif /* SERVER_WLEGL_PRIVATE_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/windowbuffer.cpp
^
|
@@ -24,14 +24,9 @@
#include <cstring>
#include <cassert>
#include "windowbuffer.h"
+#include <hybris/gralloc/gralloc.h>
RemoteWindowBuffer::~RemoteWindowBuffer()
{
- if (!m_allocated) {
- this->m_gralloc->unregisterBuffer(this->m_gralloc, this->handle);
- native_handle_close(this->handle);
- native_handle_delete(const_cast<native_handle_t*>(this->handle));
- } else if (this->m_alloc) {
- this->m_alloc->free((alloc_device_t *)this->m_alloc, this->handle);
- }
+ hybris_gralloc_release(this->handle, m_allocated);
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/common/windowbuffer.h
^
|
@@ -37,9 +37,7 @@
unsigned int stride,
unsigned int format,
unsigned int usage,
- buffer_handle_t handle,
- const gralloc_module_t *gralloc,
- const alloc_device_t *alloc = NULL
+ buffer_handle_t handle
) {
// Base members
ANativeWindowBuffer::width = width;
@@ -48,8 +46,6 @@
ANativeWindowBuffer::usage = usage;
ANativeWindowBuffer::stride = stride;
ANativeWindowBuffer::handle = handle;
- this->m_gralloc = gralloc;
- this->m_alloc = alloc;
this->m_allocated = false;
};
~RemoteWindowBuffer();
@@ -58,8 +54,6 @@
bool isAllocated() const { return m_allocated; }
private:
- const gralloc_module_t *m_gralloc;
- const alloc_device_t *m_alloc;
bool m_allocated;
};
#endif /* WINDOWBUFFER_H */
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/fbdev/Makefile.am
^
|
@@ -21,4 +21,4 @@
eglplatform_fbdev_la_LDFLAGS = \
-avoid-version -module -shared -export-dynamic \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
- $(top_builddir)/hardware/libhardware.la
+ $(top_builddir)/gralloc/libgralloc.la
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/fbdev/eglplatform_fbdev.cpp
^
|
@@ -9,46 +9,24 @@
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
+
extern "C" {
#include <eglplatformcommon.h>
};
#include "logging.h"
+#include <hybris/gralloc/gralloc.h>
-static gralloc_module_t *gralloc = 0;
-static framebuffer_device_t *framebuffer = 0;
-static alloc_device_t *alloc = 0;
static FbDevNativeWindow *_nativewindow = NULL;
extern "C" void fbdevws_init_module(struct ws_egl_interface *egl_iface)
{
- int err;
- err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
- if (gralloc==NULL) {
- fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
- assert(0);
- }
-
- err = framebuffer_open((hw_module_t *) gralloc, &framebuffer);
- if (err) {
- fprintf(stderr, "ERROR: failed to open framebuffer: (%s)\n",strerror(-err));
- assert(0);
- }
- TRACE("** framebuffer_open: status=(%s) format=x%x", strerror(-err), framebuffer->format);
-
- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
- if (err) {
- fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
- assert(0);
- }
- TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
- eglplatformcommon_init(egl_iface, gralloc, alloc);
+ hybris_gralloc_initialize(1);
+ eglplatformcommon_init(egl_iface);
}
extern "C" _EGLDisplay *fbdevws_GetDisplay(EGLNativeDisplayType display)
{
- assert (gralloc != NULL);
-
_EGLDisplay *dpy = 0;
if (display == EGL_DEFAULT_DISPLAY) {
dpy = new _EGLDisplay;
@@ -63,10 +41,9 @@
extern "C" EGLNativeWindowType fbdevws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
{
- assert (gralloc != NULL);
assert (_nativewindow == NULL);
- _nativewindow = new FbDevNativeWindow(alloc, framebuffer);
+ _nativewindow = new FbDevNativeWindow();
_nativewindow->common.incRef(&_nativewindow->common);
return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(_nativewindow);
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/fbdev/fbdev_window.cpp
^
|
@@ -30,14 +30,15 @@
};
#endif
+#include <hybris/gralloc/gralloc.h>
+
#define FRAMEBUFFER_PARTITIONS 2
static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
-FbDevNativeWindowBuffer::FbDevNativeWindowBuffer(alloc_device_t* alloc_device,
- unsigned int width,
+FbDevNativeWindowBuffer::FbDevNativeWindowBuffer(unsigned int width,
unsigned int height,
unsigned int format,
unsigned int usage)
@@ -48,13 +49,8 @@
ANativeWindowBuffer::usage = usage;
busy = 0;
status = 0;
- m_alloc = alloc_device;
- if (m_alloc) {
- status = m_alloc->alloc(m_alloc,
- width, height, format, usage,
- &handle, &stride);
- }
+ hybris_gralloc_allocate(width, height, format, usage, &handle, (uint32_t*)&stride);
TRACE("width=%d height=%d stride=%d format=x%x usage=x%x status=%s this=%p",
width, height, stride, format, usage, strerror(-status), this);
@@ -65,31 +61,26 @@
FbDevNativeWindowBuffer::~FbDevNativeWindowBuffer()
{
TRACE("%p", this);
- if (m_alloc && handle)
- m_alloc->free(m_alloc, handle);
+ hybris_gralloc_release(handle, 1);
}
////////////////////////////////////////////////////////////////////////////////
-FbDevNativeWindow::FbDevNativeWindow( alloc_device_t* alloc,
- framebuffer_device_t* fbDev)
+FbDevNativeWindow::FbDevNativeWindow()
{
- m_alloc = alloc;
- m_fbDev = fbDev;
- m_bufFormat = m_fbDev->format;
+ m_bufFormat = hybris_gralloc_fbdev_format();
m_usage = GRALLOC_USAGE_HW_FB;
m_bufferCount = 0;
m_allocateBuffers = true;
#if ANDROID_VERSION_MAJOR>=4 && ANDROID_VERSION_MINOR>=2 || ANDROID_VERSION_MAJOR>=5
- if (m_fbDev->numFramebuffers>0)
- setBufferCount(m_fbDev->numFramebuffers);
+ if (hybris_gralloc_fbdev_framebuffer_count() > 0)
+ setBufferCount(hybris_gralloc_fbdev_framebuffer_count());
else
setBufferCount(FRAMEBUFFER_PARTITIONS);
#else
setBufferCount(FRAMEBUFFER_PARTITIONS);
#endif
-
}
@@ -128,7 +119,7 @@
int FbDevNativeWindow::setSwapInterval(int interval)
{
TRACE("interval=%i", interval);
- return m_fbDev->setSwapInterval(m_fbDev, interval);
+ return hybris_gralloc_fbdev_setSwapInterval(interval);
}
@@ -279,7 +270,7 @@
HYBRIS_TRACE_BEGIN("fbdev-platform", "queueBuffer-post", "-%p", fbnb);
- int rv = m_fbDev->post(m_fbDev, fbnb->handle);
+ int rv = hybris_gralloc_fbdev_post(fbnb->handle);
if (rv!=0)
{
fprintf(stderr,"ERROR: fb->post(%s)\n",strerror(-rv));
@@ -374,7 +365,7 @@
*/
unsigned int FbDevNativeWindow::width() const
{
- unsigned int rv = m_fbDev->width;
+ unsigned int rv = hybris_gralloc_fbdev_width();
TRACE("width=%i", rv);
return rv;
}
@@ -385,7 +376,7 @@
*/
unsigned int FbDevNativeWindow::height() const
{
- unsigned int rv = m_fbDev->height;
+ unsigned int rv = hybris_gralloc_fbdev_height();
TRACE("height=%i", rv);
return rv;
}
@@ -396,7 +387,7 @@
*/
unsigned int FbDevNativeWindow::format() const
{
- unsigned int rv = m_fbDev->format;
+ unsigned int rv = hybris_gralloc_fbdev_format();
TRACE("format=x%x", rv);
return rv;
}
@@ -413,7 +404,7 @@
*/
unsigned int FbDevNativeWindow::defaultHeight() const
{
- unsigned int rv = m_fbDev->height;
+ unsigned int rv = hybris_gralloc_fbdev_height();
TRACE("height=%i", rv);
return rv;
}
@@ -424,7 +415,7 @@
*/
unsigned int FbDevNativeWindow::defaultWidth() const
{
- unsigned int rv = m_fbDev->width;
+ unsigned int rv = hybris_gralloc_fbdev_width();
TRACE("width=%i", rv);
return rv;
}
@@ -521,9 +512,8 @@
for(unsigned int i = 0; i < m_bufferCount; i++)
{
- FbDevNativeWindowBuffer *fbnb = new FbDevNativeWindowBuffer(m_alloc,
- m_fbDev->width, m_fbDev->height, m_fbDev->format,
- m_usage|GRALLOC_USAGE_HW_FB );
+ FbDevNativeWindowBuffer *fbnb = new FbDevNativeWindowBuffer(hybris_gralloc_fbdev_width(),
+ hybris_gralloc_fbdev_height(), hybris_gralloc_fbdev_format(), m_usage|GRALLOC_USAGE_HW_FB);
fbnb->common.incRef(&fbnb->common);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/fbdev/fbdev_window.h
^
|
@@ -28,8 +28,7 @@
friend class FbDevNativeWindow;
protected:
- FbDevNativeWindowBuffer(alloc_device_t* alloc,
- unsigned int width,
+ FbDevNativeWindowBuffer(unsigned int width,
unsigned int height,
unsigned int format,
unsigned int usage) ;
@@ -38,14 +37,12 @@
protected:
int busy;
int status;
- alloc_device_t* m_alloc;
};
class FbDevNativeWindow : public BaseNativeWindow {
public:
- FbDevNativeWindow(alloc_device_t* alloc,
- framebuffer_device_t* fbDev);
+ FbDevNativeWindow();
~FbDevNativeWindow();
// overloads from BaseNativeWindow
@@ -77,8 +74,6 @@
void reallocateBuffers();
private:
- framebuffer_device_t* m_fbDev;
- alloc_device_t* m_alloc;
unsigned int m_usage;
unsigned int m_bufFormat;
unsigned int m_bufferCount;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/hwcomposer/Makefile.am
^
|
@@ -28,7 +28,7 @@
libhybris_hwcomposerwindow_la_LDFLAGS = \
-version-info "1":"0":"0" \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
- $(top_builddir)/hardware/libhardware.la
+ $(top_builddir)/gralloc/libgralloc.la
if HAS_ANDROID_4_2_0
libhybris_hwcomposerwindow_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
@@ -58,5 +58,5 @@
eglplatform_hwcomposer_la_LDFLAGS = \
-avoid-version -module -shared -export-dynamic \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
- $(top_builddir)/hardware/libhardware.la
+ $(top_builddir)/gralloc/libgralloc.la
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/hwcomposer/eglplatform_hwcomposer.cpp
^
|
@@ -15,31 +15,18 @@
#include "logging.h"
-static gralloc_module_t *gralloc = 0;
-static alloc_device_t *alloc = 0;
+#include <hybris/gralloc/gralloc.h>
+
static HWComposerNativeWindow *_nativewindow = NULL;
extern "C" void hwcomposerws_init_module(struct ws_egl_interface *egl_iface)
{
- int err;
- err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
- if (gralloc==NULL) {
- fprintf(stderr, "failed to get gralloc module: (%s)\n",strerror(-err));
- assert(0);
- }
-
- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
- if (err) {
- fprintf(stderr, "ERROR: failed to open gralloc: (%s)\n",strerror(-err));
- assert(0);
- }
- TRACE("** gralloc_open %p status=%s", gralloc, strerror(-err));
- eglplatformcommon_init(egl_iface, gralloc, alloc);
+ hybris_gralloc_initialize(0);
+ eglplatformcommon_init(egl_iface);
}
extern "C" _EGLDisplay *hwcomposerws_GetDisplay(EGLNativeDisplayType display)
{
- assert (gralloc != NULL);
_EGLDisplay *dpy = 0;
if (display == EGL_DEFAULT_DISPLAY) {
dpy = new _EGLDisplay;
@@ -54,11 +41,9 @@
extern "C" EGLNativeWindowType hwcomposerws_CreateWindow(EGLNativeWindowType win, _EGLDisplay *display)
{
- assert (gralloc != NULL);
assert (_nativewindow == NULL);
HWComposerNativeWindow *window = static_cast<HWComposerNativeWindow *>((ANativeWindow *) win);
- window->setup(gralloc, alloc);
_nativewindow = window;
_nativewindow->common.incRef(&_nativewindow->common);
return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(_nativewindow);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/hwcomposer/hwcomposer_window.cpp
^
|
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+#ifndef ANDROID_BUILD
#include <android-config.h>
+#include "logging.h"
+#endif
+
#include "hwcomposer_window.h"
#include "hwcomposer.h"
-#include "logging.h"
#include <errno.h>
#include <assert.h>
@@ -30,7 +33,15 @@
extern "C" {
#include <sync/sync.h>
};
-
+
+#ifdef ANDROID_BUILD
+#define TRACE(...)
+#define HYBRIS_TRACE_BEGIN(...)
+#define HYBRIS_TRACE_END(...)
+#include "hybris-gralloc.h"
+#else
+#include <hybris/gralloc/gralloc.h>
+#endif
extern "C" struct ANativeWindow *HWCNativeWindowCreate(unsigned int width, unsigned int height, unsigned int format, HWCPresentCallback present, void *cb_data)
{
@@ -84,8 +95,7 @@
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
-HWComposerNativeWindowBuffer::HWComposerNativeWindowBuffer(alloc_device_t* alloc_device,
- unsigned int width,
+HWComposerNativeWindowBuffer::HWComposerNativeWindowBuffer(unsigned int width,
unsigned int height,
unsigned int format,
unsigned int usage)
@@ -97,13 +107,8 @@
fenceFd = -1;
busy = 0;
status = 0;
- m_alloc = alloc_device;
- if (m_alloc) {
- status = m_alloc->alloc(m_alloc,
- width, height, format, usage,
- &handle, &stride);
- }
+ hybris_gralloc_allocate(width, height, format, usage, &handle, (uint32_t*)&stride);
TRACE("width=%d height=%d stride=%d format=x%x usage=x%x status=%s this=%p",
width, height, stride, format, usage, strerror(-status), this);
@@ -114,9 +119,7 @@
HWComposerNativeWindowBuffer::~HWComposerNativeWindowBuffer()
{
TRACE("%p", this);
- if (m_alloc && handle)
- m_alloc->free(m_alloc, handle);
-
+ hybris_gralloc_release(handle, 1);
}
@@ -124,7 +127,6 @@
HWComposerNativeWindow::HWComposerNativeWindow(unsigned int width, unsigned int height, unsigned int format)
{
pthread_mutex_init(&m_mutex, 0);
- m_alloc = NULL;
m_width = width;
m_height = height;
m_bufFormat = format;
@@ -133,11 +135,6 @@
m_nextBuffer = 0;
}
-void HWComposerNativeWindow::setup(gralloc_module_t* gralloc, alloc_device_t* alloc)
-{
- m_alloc = alloc;
-}
-
HWComposerNativeWindow::~HWComposerNativeWindow()
{
destroyBuffers();
@@ -489,7 +486,7 @@
for(unsigned int i = 0; i < m_bufferCount; i++)
{
HWComposerNativeWindowBuffer *b
- = new HWComposerNativeWindowBuffer(m_alloc, m_width, m_height, m_bufFormat, m_usage);
+ = new HWComposerNativeWindowBuffer(m_width, m_height, m_bufFormat, m_usage);
b->common.incRef(&b->common);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/hwcomposer/hwcomposer_window.h
^
|
@@ -28,18 +28,16 @@
friend class HWComposerNativeWindow;
protected:
- HWComposerNativeWindowBuffer(alloc_device_t* alloc,
- unsigned int width,
- unsigned int height,
- unsigned int format,
- unsigned int usage) ;
+ HWComposerNativeWindowBuffer(unsigned int width,
+ unsigned int height,
+ unsigned int format,
+ unsigned int usage) ;
virtual ~HWComposerNativeWindowBuffer() ;
protected:
int busy;
int fenceFd;
int status;
- alloc_device_t* m_alloc;
};
@@ -47,8 +45,6 @@
public:
HWComposerNativeWindow(unsigned int width, unsigned int height, unsigned int format);
~HWComposerNativeWindow();
- void setup(gralloc_module_t* gralloc, alloc_device_t* alloc);
-
int getFenceBufferFd(HWComposerNativeWindowBuffer *buffer);
void setFenceBufferFd(HWComposerNativeWindowBuffer *buffer, int fd);
@@ -82,8 +78,6 @@
void allocateBuffers();
private:
- framebuffer_device_t* m_fbDev;
- alloc_device_t* m_alloc;
unsigned int m_usage;
unsigned int m_bufFormat;
std::vector<HWComposerNativeWindowBuffer*> m_bufList;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/null/Makefile.am
^
|
@@ -14,7 +14,7 @@
eglplatform_null_la_LDFLAGS = \
-avoid-version -module -shared -export-dynamic \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
- $(top_builddir)/hardware/libhardware.la \
+ $(top_builddir)/gralloc/libgralloc.la \
$(WAYLAND_SERVER_LIBS)
if WANT_DEBUG
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/null/eglplatform_null.c
^
|
@@ -7,9 +7,7 @@
#include <hybris/common/binding.h>
#include <eglplatformcommon.h>
#include "logging.h"
-
-static gralloc_module_t *gralloc = 0;
-static alloc_device_t *alloc = 0;
+#include <hybris/gralloc/gralloc.h>
#pragma GCC visibility push(hidden)
HYBRIS_LIBRARY_INITIALIZE(nullui, "/system/lib/libui.so");
@@ -19,12 +17,8 @@
static void nullws_init_module(struct ws_egl_interface *egl_iface)
{
- int err;
- hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
- TRACE("++ %lu wayland: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err));
- eglplatformcommon_init(egl_iface, gralloc, alloc);
-
+ hybris_gralloc_initialize(0);
+ eglplatformcommon_init(egl_iface);
}
static struct _EGLDisplay *nullws_GetDisplay(EGLNativeDisplayType display)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/wayland/Makefile.am
^
|
@@ -6,6 +6,7 @@
-I$(top_srcdir)/include \
-I$(top_srcdir)/egl \
-I$(top_srcdir)/egl/platforms/common \
+ -I$(top_builddir)/egl/platforms/common \
$(ANDROID_HEADERS_CFLAGS) \
$(WAYLAND_CLIENT_CFLAGS)
@@ -30,7 +31,7 @@
eglplatform_wayland_la_LDFLAGS = \
-avoid-version -module -shared -export-dynamic \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
- $(top_builddir)/hardware/libhardware.la \
+ $(top_builddir)/gralloc/libgralloc.la \
$(WAYLAND_CLIENT_LIBS)
if HAS_ANDROID_4_2_0
eglplatform_wayland_la_LDFLAGS += $(top_builddir)/libsync/libsync.la
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
^
|
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
+#include <dlfcn.h>
extern "C" {
#include <eglplatformcommon.h>
};
@@ -48,22 +49,26 @@
#include <wayland-egl.h>
}
+#include <hybris/gralloc/gralloc.h>
#include "wayland_window.h"
#include "logging.h"
#include "wayland-egl-priv.h"
#include "server_wlegl_buffer.h"
#include "wayland-android-client-protocol.h"
-static gralloc_module_t *gralloc = 0;
-static alloc_device_t *alloc = 0;
-
-
static const char * (*_eglQueryString)(EGLDisplay dpy, EGLint name) = NULL;
static __eglMustCastToProperFunctionPointerType (*_eglGetProcAddress)(const char *procname) = NULL;
static EGLSyncKHR (*_eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) = NULL;
static EGLBoolean (*_eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync) = NULL;
static EGLint (*_eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) = NULL;
+/* The following function is implemented in libhybris's libEGL.so.
+ * However, eglplatform_wayland.so is not linking to libEGL directly,
+ * causing undefined symbol errors during loading, if libEGL was not
+ * already loaded by some other dependencies. Therefore, we should try
+ * to load libEGL at runtime here and resolve this function dynamically */
+typedef struct _EGLDisplay *(*PFNHYBRISEGLDISPLAYGETMAPPINGPROC)(EGLDisplay dpy);
+
struct WaylandDisplay {
_EGLDisplay base;
@@ -75,11 +80,8 @@
extern "C" void waylandws_init_module(struct ws_egl_interface *egl_iface)
{
- int err;
- hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc);
- err = gralloc_open((const hw_module_t *) gralloc, &alloc);
- TRACE("++ %lu wayland: got gralloc %p err:%s", pthread_self(), gralloc, strerror(-err));
- eglplatformcommon_init(egl_iface, gralloc, alloc);
+ hybris_gralloc_initialize(0);
+ eglplatformcommon_init(egl_iface);
}
static void _init_egl_funcs(EGLDisplay display)
@@ -140,7 +142,7 @@
extern "C" _EGLDisplay *waylandws_GetDisplay(EGLNativeDisplayType display)
{
WaylandDisplay *wdpy = new WaylandDisplay;
- wdpy->wl_dpy = (wl_display *)display;
+ wdpy->wl_dpy = display ? (wl_display *)display : wl_display_connect(NULL);
wdpy->wlegl = NULL;
wdpy->queue = wl_display_create_queue(wdpy->wl_dpy);
wdpy->registry = wl_display_get_registry(wdpy->wl_dpy);
@@ -190,7 +192,7 @@
}
assert(ret >= 0);
- WaylandNativeWindow *window = new WaylandNativeWindow((struct wl_egl_window *) win, wdpy->wl_dpy, wdpy->wlegl, alloc, gralloc);
+ WaylandNativeWindow *window = new WaylandNativeWindow((struct wl_egl_window *) win, wdpy->wl_dpy, wdpy->wlegl);
window->common.incRef(&window->common);
return (EGLNativeWindowType) static_cast<struct ANativeWindow *>(window);
}
@@ -208,6 +210,36 @@
return ((WaylandNativeWindow *) eglwin->nativewindow)->postBuffer((ANativeWindowBuffer *) buffer);
}
+/**
+ * Loads libhybris's libEGL at runtime to call hybris_egl_display_get_mapping()
+ */
+static struct _EGLDisplay *_hybris_egl_display_get_mapping(EGLDisplay dpy)
+{
+ static void *libEGL_handle = NULL;
+ static PFNHYBRISEGLDISPLAYGETMAPPINGPROC hybris_egl_display_get_mapping_fn = NULL;
+
+ if (!libEGL_handle) {
+ dlerror(); // cleanup error buffer
+ libEGL_handle = dlopen("libEGL.so.1", RTLD_NOW | RTLD_GLOBAL);
+ if (!libEGL_handle) {
+ HYBRIS_ERROR("ERROR: Failed to dlopen libEGL! %s", dlerror());
+ abort();
+ }
+ }
+
+ if (!hybris_egl_display_get_mapping_fn) {
+ dlerror(); // cleanup error buffer
+ hybris_egl_display_get_mapping_fn = (PFNHYBRISEGLDISPLAYGETMAPPINGPROC)dlsym(
+ libEGL_handle, "hybris_egl_display_get_mapping");
+ if (!hybris_egl_display_get_mapping_fn) {
+ HYBRIS_ERROR("ERROR: Cannot resolve 'hybris_egl_display_get_mapping' in libEGL! %s", dlerror());
+ abort();
+ }
+ }
+
+ return hybris_egl_display_get_mapping_fn(dpy);
+}
+
extern "C" wl_buffer *waylandws_createWlBuffer(EGLDisplay dpy, EGLImageKHR image)
{
egl_image *img = reinterpret_cast<egl_image *>(image);
@@ -217,7 +249,7 @@
return NULL;
}
if (img->target == EGL_WAYLAND_BUFFER_WL) {
- WaylandDisplay *wdpy = (WaylandDisplay *)hybris_egl_display_get_mapping(dpy);
+ WaylandDisplay *wdpy = (WaylandDisplay *)_hybris_egl_display_get_mapping(dpy);
server_wlegl_buffer *buf = server_wlegl_buffer_from((wl_resource *)img->egl_buffer);
WaylandNativeWindowBuffer wnb(buf->buf);
// The buffer will be managed by the app, so pass NULL as the queue so that
@@ -253,8 +285,8 @@
const char *ret = eglplatformcommon_eglQueryString(dpy, name, real_eglQueryString);
if (ret && name == EGL_EXTENSIONS)
{
- static char eglextensionsbuf[1024];
- snprintf(eglextensionsbuf, 1022, "%s %s", ret,
+ static char eglextensionsbuf[2048];
+ snprintf(eglextensionsbuf, 2046, "%s %s", ret,
"EGL_EXT_swap_buffers_with_damage EGL_WL_create_wayland_buffer_from_image"
);
ret = eglextensionsbuf;
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/wayland/wayland_window.cpp
^
|
@@ -102,7 +102,11 @@
void WaylandNativeWindow::free_callback(struct wl_egl_window *egl_window, void *)
{
- ((WaylandNativeWindow*)(egl_window->nativewindow))->m_window = 0;
+ WaylandNativeWindow *native = (WaylandNativeWindow*)egl_window->nativewindow;
+
+ native->lock();
+ native->m_window = 0;
+ native->unlock();
}
void WaylandNativeWindow::lock()
@@ -172,7 +176,7 @@
wayland_frame_callback
};
-WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, android_wlegl *wlegl, alloc_device_t* alloc_device, gralloc_module_t *gralloc)
+WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, android_wlegl *wlegl)
: m_android_wlegl(wlegl)
{
int wayland_ok;
@@ -196,9 +200,6 @@
// This is the default as per the EGL documentation
this->m_swap_interval = 1;
- this->m_alloc = alloc_device;
- m_gralloc = gralloc;
-
m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
@@ -218,7 +219,7 @@
if (frame_callback)
wl_callback_destroy(frame_callback);
wl_event_queue_destroy(wl_queue);
- if (m_window) {
+ if (m_window) {
m_window->nativewindow = NULL;
m_window->resize_callback = NULL;
m_window->free_callback = NULL;
@@ -371,12 +372,12 @@
HYBRIS_TRACE_END("wayland-platform", "dequeueBuffer_wait_for_buffer", "");
/* If the buffer doesn't match the window anymore, re-allocate */
- if (wnb->width != m_window->width || wnb->height != m_window->height
+ if (wnb->width != m_width || wnb->height != m_height
|| wnb->format != m_format || wnb->usage != m_usage)
{
TRACE("wnb:%p,win:%p %i,%i %i,%i x%x,x%x x%x,x%x",
wnb,m_window,
- wnb->width,m_window->width, wnb->height,m_window->height,
+ wnb->width,m_width, wnb->height,m_height,
wnb->format,m_format, wnb->usage,m_usage);
destroyBuffer(wnb);
m_bufList.erase(it);
@@ -507,6 +508,10 @@
{
int ret = 0;
lock();
+ if (!m_window) {
+ unlock();
+ return;
+ }
WaylandNativeWindowBuffer *wnb = queue.front();
if (!wnb) {
@@ -526,6 +531,7 @@
}
if (ret < 0) {
HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb);
+ unlock();
return;
}
@@ -748,10 +754,10 @@
WaylandNativeWindowBuffer *wnb;
#ifndef HYBRIS_NO_SERVER_SIDE_BUFFERS
- wnb = new ServerWaylandBuffer(m_width, m_height, m_format, m_usage, m_gralloc, m_android_wlegl, wl_queue);
+ wnb = new ServerWaylandBuffer(m_width, m_height, m_format, m_usage, m_android_wlegl, wl_queue);
wayland_roundtrip(this);
#else
- wnb = new ClientWaylandBuffer(m_alloc, m_width, m_height, m_format, m_usage);
+ wnb = new ClientWaylandBuffer(m_width, m_height, m_format, m_usage);
#endif
m_bufList.push_back(wnb);
++m_freeBufs;
@@ -866,7 +872,7 @@
wsb->format = format;
wsb->stride = stride;
- int ret = wsb->m_gralloc->registerBuffer(wsb->m_gralloc, wsb->handle);
+ int ret = hybris_gralloc_retain(wsb->handle);
if (ret) {
fprintf(stderr,"failed to register buffer\n");
return;
@@ -882,13 +888,12 @@
ssb_buffer,
};
-ServerWaylandBuffer::ServerWaylandBuffer(unsigned int w, unsigned int h, int f, int u, gralloc_module_t *gralloc, android_wlegl *android_wlegl, struct wl_event_queue *queue)
+ServerWaylandBuffer::ServerWaylandBuffer(unsigned int w, unsigned int h, int f, int u, android_wlegl *android_wlegl, struct wl_event_queue *queue)
: WaylandNativeWindowBuffer()
, m_buf(0)
{
ANativeWindowBuffer::width = w;
ANativeWindowBuffer::height = h;
- m_gralloc = gralloc;
usage = u;
wl_array_init(&ints);
@@ -904,9 +909,7 @@
if (m_buf)
wl_buffer_destroy(m_buf);
- m_gralloc->unregisterBuffer(m_gralloc, handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle_t *>(handle));
+ hybris_gralloc_release(handle, 1);
wl_array_release(&ints);
wl_array_release(&fds);
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/platforms/wayland/wayland_window.h
^
|
@@ -28,7 +28,9 @@
#define Wayland_WINDOW_H
#include "nativewindowbase.h"
#include <linux/fb.h>
-#include <hardware/gralloc.h>
+
+#include <hybris/gralloc/gralloc.h>
+
extern "C" {
#include <wayland-client.h>
@@ -36,6 +38,7 @@
#include "wayland-android-client-protocol.h"
#include <pthread.h>
}
+
#include <list>
#include <deque>
@@ -80,11 +83,9 @@
friend class WaylandNativeWindow;
protected:
ClientWaylandBuffer()
- : m_alloc(0)
- {}
+ : {}
- ClientWaylandBuffer(alloc_device_t* alloc_device,
- unsigned int width,
+ ClientWaylandBuffer( unsigned int width,
unsigned int height,
unsigned int format,
unsigned int usage)
@@ -98,9 +99,7 @@
this->creation_callback = NULL;
this->busy = 0;
this->other = NULL;
- this->m_alloc = alloc_device;
- int alloc_ok = this->m_alloc->alloc(this->m_alloc,
- this->width ? this->width : 1, this->height ? this->height : 1,
+ int alloc_ok = hybris_gralloc_allocate(this->width ? this->width : 1, this->height ? this->height : 1,
this->format, this->usage,
&this->handle, &this->stride);
assert(alloc_ok == 0);
@@ -110,8 +109,7 @@
~ClientWaylandBuffer()
{
- if (this->m_alloc)
- m_alloc->free(m_alloc, this->handle);
+ hybris_gralloc_release(this->handle, 1);
}
void init(struct android_wlegl *android_wlegl,
@@ -120,7 +118,6 @@
protected:
void* vaddr;
- alloc_device_t* m_alloc;
public:
@@ -131,7 +128,7 @@
class ServerWaylandBuffer : public WaylandNativeWindowBuffer
{
public:
- ServerWaylandBuffer(unsigned int w, unsigned int h, int format, int usage, gralloc_module_t *gralloc, android_wlegl *android_wlegl, struct wl_event_queue *queue);
+ ServerWaylandBuffer(unsigned int w, unsigned int h, int format, int usage, android_wlegl *android_wlegl, struct wl_event_queue *queue);
~ServerWaylandBuffer();
void init(struct android_wlegl *android_wlegl,
struct wl_display *display,
@@ -139,7 +136,6 @@
struct wl_array ints;
struct wl_array fds;
- gralloc_module_t *m_gralloc;
wl_buffer *m_buf;
};
@@ -147,7 +143,7 @@
class WaylandNativeWindow : public BaseNativeWindow {
public:
- WaylandNativeWindow(struct wl_egl_window *win, struct wl_display *display, android_wlegl *wlegl, alloc_device_t* alloc_device, gralloc_module_t *gralloc);
+ WaylandNativeWindow(struct wl_egl_window *win, struct wl_display *display, android_wlegl *wlegl);
~WaylandNativeWindow();
void lock();
@@ -210,7 +206,6 @@
unsigned int m_defaultHeight;
unsigned int m_usage;
struct android_wlegl *m_android_wlegl;
- alloc_device_t* m_alloc;
pthread_mutex_t mutex;
pthread_cond_t cond;
int m_queueReads;
@@ -219,7 +214,6 @@
struct wl_callback *frame_callback;
int m_swap_interval;
static int wayland_roundtrip(WaylandNativeWindow *display);
- gralloc_module_t *m_gralloc;
};
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/egl/ws.c
^
|
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
+#include <sys/auxv.h>
static struct ws_module *ws = NULL;
@@ -40,7 +41,14 @@
if (egl_platform == NULL)
egl_platform = DEFAULT_EGL_PLATFORM;
- snprintf(ws_name, 2048, PKGLIBDIR "eglplatform_%s.so", egl_platform);
+ const char *eglplatform_dir = PKGLIBDIR;
+ const char *user_eglplatform_dir = getauxval(AT_SECURE)
+ ? NULL
+ : getenv("HYBRIS_EGLPLATFORM_DIR");
+ if (user_eglplatform_dir)
+ eglplatform_dir = user_eglplatform_dir;
+
+ snprintf(ws_name, 2048, "%s/eglplatform_%s.so", eglplatform_dir, egl_platform);
void *wsmod = (void *) dlopen(ws_name, RTLD_LAZY);
if (wsmod==NULL)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/glesv1/glesv1_cm.c
^
|
@@ -26,6 +26,8 @@
#include <hybris/common/binding.h>
+#include "../egl/ws.h"
+
#define GLESV1_CM_LIBRARY_PATH "libGLESv1_CM.so"
HYBRIS_LIBRARY_INITIALIZE(glesv1_cm, GLESV1_CM_LIBRARY_PATH);
@@ -187,7 +189,6 @@
HYBRIS_IMPLEMENT_VOID_FUNCTION1(glesv1_cm, glDrawTexxvOES, const GLfixed *);
HYBRIS_IMPLEMENT_VOID_FUNCTION5(glesv1_cm, glDrawTexfOES, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
HYBRIS_IMPLEMENT_VOID_FUNCTION1(glesv1_cm, glDrawTexfvOES, const GLfloat *);
-HYBRIS_IMPLEMENT_VOID_FUNCTION2(glesv1_cm, glEGLImageTargetTexture2DOES, GLenum, GLeglImageOES);
HYBRIS_IMPLEMENT_VOID_FUNCTION2(glesv1_cm, glEGLImageTargetRenderbufferStorageOES, GLenum, GLeglImageOES);
HYBRIS_IMPLEMENT_VOID_FUNCTION2(glesv1_cm, glAlphaFuncxOES, GLenum, GLclampx);
HYBRIS_IMPLEMENT_VOID_FUNCTION4(glesv1_cm, glClearColorxOES, GLclampx, GLclampx, GLclampx, GLclampx);
@@ -304,3 +305,11 @@
HYBRIS_IMPLEMENT_VOID_FUNCTION4(glesv1_cm, glExtGetProgramBinarySourceQCOM, GLuint, GLenum, GLchar *, GLint *);
HYBRIS_IMPLEMENT_VOID_FUNCTION5(glesv1_cm, glStartTilingQCOM, GLuint, GLuint, GLuint, GLuint, GLbitfield);
HYBRIS_IMPLEMENT_VOID_FUNCTION1(glesv1_cm, glEndTilingQCOM, GLbitfield);
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ static void (*_glEGLImageTargetTexture2DOES)(GLenum, GLeglImageOES) FP_ATTRIB = NULL;
+ HYBRIS_DLSYSM(glesv1_cm, &_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES");
+ struct egl_image *img = image;
+ _glEGLImageTargetTexture2DOES(target, img ? img->egl_image : NULL);
+}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/glesv2/glesv2.c
^
|
@@ -25,6 +25,8 @@
#include <hybris/common/binding.h>
+#include "../egl/ws.h"
+
static void *_libglesv2 = NULL;
static void (*_glActiveTexture)(GLenum texture) = NULL;
@@ -1044,7 +1046,8 @@
void glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
{
- (*_glEGLImageTargetTexture2DOES)(target, image);
+ struct egl_image *img = image;
+ (*_glEGLImageTargetTexture2DOES)(target, img ? img->egl_image : NULL);
}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/gralloc/GrallocUsageConversion.cpp
^
|
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#include <hybris/grallocusage/GrallocUsageConversion.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+
+#ifndef ANDROID_BUILD
+#include <android-config.h>
+#endif
+
+void android_convertGralloc0To1Usage(int32_t usage, uint64_t* producerUsage,
+ uint64_t* consumerUsage) {
+ constexpr uint64_t PRODUCER_MASK =
+ GRALLOC1_PRODUCER_USAGE_CPU_READ |
+ /* GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN | */
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE |
+ /* GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | */
+ GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET | GRALLOC1_PRODUCER_USAGE_PROTECTED |
+ GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER
+#if ANDROID_VERSION_MAJOR >= 8
+ | GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA
+#endif
+ ;
+ constexpr uint64_t CONSUMER_MASK =
+ GRALLOC1_CONSUMER_USAGE_CPU_READ |
+ /* GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN | */
+ GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER |
+ GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET | GRALLOC1_CONSUMER_USAGE_CURSOR |
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CAMERA |
+ GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT
+#if ANDROID_VERSION_MAJOR >= 8
+ | GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER
+#endif
+ ;
+ *producerUsage = static_cast<uint64_t>(usage) & PRODUCER_MASK;
+ *consumerUsage = static_cast<uint64_t>(usage) & CONSUMER_MASK;
+ if ((static_cast<uint32_t>(usage) & GRALLOC_USAGE_SW_READ_OFTEN) == GRALLOC_USAGE_SW_READ_OFTEN) {
+ *producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+ *consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+ }
+ if ((static_cast<uint32_t>(usage) & GRALLOC_USAGE_SW_WRITE_OFTEN) ==
+ GRALLOC_USAGE_SW_WRITE_OFTEN) {
+ *producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+ }
+}
+
+int32_t android_convertGralloc1To0Usage(uint64_t producerUsage, uint64_t consumerUsage) {
+ static_assert(uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
+ uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN),
+ "expected ConsumerUsage and ProducerUsage CPU_READ_OFTEN bits to match");
+ uint64_t merged = producerUsage | consumerUsage;
+ if ((merged & (GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)) ==
+ GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
+ merged &= ~uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
+ merged |= GRALLOC_USAGE_SW_READ_OFTEN;
+ }
+ if ((merged & (GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) ==
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
+ merged &= ~uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
+ merged |= GRALLOC_USAGE_SW_WRITE_OFTEN;
+ }
+ return static_cast<int32_t>(merged);
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/gralloc/Makefile.am
^
|
@@ -0,0 +1,28 @@
+lib_LTLIBRARIES = \
+ libgralloc.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgralloc.pc
+
+libgralloc_la_SOURCES = gralloc.c
+
+if HAS_GRALLOC1_HEADER
+libgralloc_la_SOURCES += GrallocUsageConversion.cpp
+endif
+
+if HAS_GRALLOC1_HEADER
+libgralloc_la_CFLAGS = -DHAS_GRALLOC1_HEADER=1
+else
+libgralloc_la_CFLAGS = -DHAS_GRALLOC1_HEADER=0
+endif
+libgralloc_la_CFLAGS += -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
+libgralloc_la_CXXFLAGS = -std=gnu++11 -I$(top_srcdir)/include
+if WANT_TRACE
+libgralloc_la_CFLAGS += -DDEBUG
+endif
+if WANT_DEBUG
+libgralloc_la_CFLAGS += -ggdb -O0
+endif
+libgralloc_la_LDFLAGS = \
+ $(top_builddir)/hardware/libhardware.la \
+ -version-info "1":"0":"0"
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/gralloc/gralloc.c
^
|
@@ -0,0 +1,356 @@
+#include <stdlib.h>
+
+#include <hardware/hardware.h>
+
+#include <hardware/gralloc.h>
+#if HAS_GRALLOC1_HEADER
+#include <hybris/grallocusage/GrallocUsageConversion.h>
+#include <hardware/gralloc1.h>
+#endif
+#include <hardware/fb.h>
+
+#ifdef ANDROID_BUILD
+#include "hybris-gralloc.h"
+#else
+#include <android-config.h>
+#include <hybris/gralloc/gralloc.h>
+#include <hybris/common/binding.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <dlfcn.h>
+
+static int version = -1;
+static hw_module_t *gralloc_hardware_module = NULL;
+
+static framebuffer_device_t *framebuffer_device = NULL;
+static gralloc_module_t *gralloc0_module;
+static alloc_device_t *gralloc0_alloc;
+
+#if HAS_GRALLOC1_HEADER
+static gralloc1_device_t *gralloc1_device = NULL;
+static int gralloc1_release_implies_delete = 0;
+static GRALLOC1_PFN_CREATE_DESCRIPTOR gralloc1_create_descriptor = NULL;
+static GRALLOC1_PFN_DESTROY_DESCRIPTOR gralloc1_destroy_descriptor = NULL;
+static GRALLOC1_PFN_SET_CONSUMER_USAGE gralloc1_set_consumer_usage = NULL;
+static GRALLOC1_PFN_SET_DIMENSIONS gralloc1_set_dimensions = NULL;
+static GRALLOC1_PFN_SET_FORMAT gralloc1_set_format = NULL;
+static GRALLOC1_PFN_SET_PRODUCER_USAGE gralloc1_set_producer_usage = NULL;
+static GRALLOC1_PFN_GET_BACKING_STORE gralloc1_get_backing_store = NULL;
+static GRALLOC1_PFN_GET_CONSUMER_USAGE gralloc1_get_consumer_usage = NULL;
+static GRALLOC1_PFN_GET_DIMENSIONS gralloc1_get_dimensions = NULL;
+static GRALLOC1_PFN_GET_FORMAT gralloc1_get_format = NULL;
+static GRALLOC1_PFN_GET_PRODUCER_USAGE gralloc1_get_producer_usage = NULL;
+static GRALLOC1_PFN_GET_STRIDE gralloc1_get_stride = NULL;
+static GRALLOC1_PFN_ALLOCATE gralloc1_allocate = NULL;
+static GRALLOC1_PFN_RETAIN gralloc1_retain = NULL;
+static GRALLOC1_PFN_RELEASE gralloc1_release = NULL;
+static GRALLOC1_PFN_GET_NUM_FLEX_PLANES gralloc1_get_num_flex_planes = NULL;
+static GRALLOC1_PFN_LOCK gralloc1_lock = NULL;
+static GRALLOC1_PFN_LOCK_FLEX gralloc1_lock_flex = NULL;
+static GRALLOC1_PFN_UNLOCK gralloc1_unlock = NULL;
+#ifdef GRALLOC1_PFN_SET_LAYER_COUNT
+static GRALLOC1_PFN_SET_LAYER_COUNT gralloc1_set_layer_count = NULL;
+static GRALLOC1_PFN_GET_LAYER_COUNT gralloc1_get_layer_count = NULL;
+#endif
+
+static void gralloc1_init(void);
+#endif
+
+// simple macros to make sure the code is only compiled if we actually have the
+// header to be able to compile it.
+// we could also use Gralloc1On0Adapter, but that would mean we need to import
+// headers and cpp files from android 8, which may not compile against older
+// android trees.
+#if HAS_GRALLOC1_HEADER
+#define GRALLOC0(code) (version == 0) { code }
+#define GRALLOC1(code) (version == 1) { code }
+#else
+#define GRALLOC0(code) (version == 0) { code }
+#define GRALLOC1(code) (0) {}
+#endif
+
+#define NO_GRALLOC { fprintf(stderr, "%s:%d: called gralloc method without gralloc loaded\n", __func__, __LINE__); assert(NULL); }
+
+void hybris_gralloc_deinitialize(void);
+
+void hybris_gralloc_initialize(int framebuffer)
+{
+ if (version == -1) {
+ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **)&gralloc_hardware_module) == 0) {
+#if HAS_GRALLOC1_HEADER
+ if ((gralloc1_open(gralloc_hardware_module, &gralloc1_device) == 0) && (gralloc1_device != NULL)) {
+ // success
+ gralloc1_init();
+ version = 1;
+ atexit(hybris_gralloc_deinitialize);
+ } else
+#endif
+ if (framebuffer) {
+ if (framebuffer_open(gralloc_hardware_module, &framebuffer_device) == 0) {
+ if ((gralloc_open(gralloc_hardware_module, &gralloc0_alloc) == 0) && gralloc0_alloc != NULL) {
+ // success
+ gralloc0_module = (struct gralloc_module_t*)gralloc_hardware_module;
+ version = 0;
+ atexit(hybris_gralloc_deinitialize);
+ } else {
+ fprintf(stderr, "failed to open the gralloc 0 module (framebuffer was requested therefore defaulted to version 0)\n");
+ assert(NULL);
+ }
+ } else {
+ fprintf(stderr, "failed to open the framebuffer module\n");
+ assert(NULL);
+ }
+ } else
+ if ((gralloc_open(gralloc_hardware_module, &gralloc0_alloc) == 0) && gralloc0_alloc != NULL) {
+ // success
+ gralloc0_module = (struct gralloc_module_t*)gralloc_hardware_module;
+ version = 0;
+ atexit(hybris_gralloc_deinitialize);
+ } else {
+ // fail
+ framebuffer_device = NULL;
+#if HAS_GRALLOC1_HEADER
+ gralloc1_device = NULL;
+#endif
+ version = -2;
+ fprintf(stderr, "failed to open gralloc module with both version 0 and 1 methods\n");
+ hybris_gralloc_deinitialize();
+ assert(NULL);
+ }
+ } else {
+ fprintf(stderr, "failed to find/load gralloc module\n");
+ assert(NULL);
+ }
+ } else {
+ // shouldn't reach here.
+ assert(NULL);
+ }
+}
+
+void hybris_gralloc_deinitialize(void)
+{
+ if (framebuffer_device) framebuffer_close(framebuffer_device);
+ framebuffer_device = NULL;
+
+ if (gralloc0_alloc) gralloc_close(gralloc0_alloc);
+ gralloc0_alloc = NULL;
+
+#if HAS_GRALLOC1_HEADER
+ if (gralloc1_device) gralloc1_close(gralloc1_device);
+ gralloc1_device = NULL;
+#endif
+
+#ifdef ANDROID_BUILD
+ if (gralloc_hardware_module) dlclose(gralloc_hardware_module->dso);
+#else
+ if (gralloc_hardware_module) android_dlclose(gralloc_hardware_module->dso);
+#endif
+ gralloc_hardware_module = NULL;
+}
+
+#if HAS_GRALLOC1_HEADER
+static void gralloc1_init(void)
+{
+ uint32_t count = 0;
+ gralloc1_device->getCapabilities(gralloc1_device, &count, NULL);
+
+ if (count >= 1) {
+ int32_t i;
+ int32_t *gralloc1_capabilities = (int32_t*)malloc(sizeof(int32_t) * count);
+
+ gralloc1_device->getCapabilities(gralloc1_device, &count, gralloc1_capabilities);
+
+ // currently the only one that affects us/interests us is release imply delete.
+ for (i = 0; i < count; i++) {
+#if ANDROID_VERSION_MAJOR >= 8
+ if (gralloc1_capabilities[i] == GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE) {
+ gralloc1_release_implies_delete = 1;
+ }
+#endif
+ }
+
+ free(gralloc1_capabilities);
+ }
+
+ gralloc1_create_descriptor = (GRALLOC1_PFN_CREATE_DESCRIPTOR)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_CREATE_DESCRIPTOR);
+ gralloc1_destroy_descriptor = (GRALLOC1_PFN_DESTROY_DESCRIPTOR)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR);
+ gralloc1_set_consumer_usage = (GRALLOC1_PFN_SET_CONSUMER_USAGE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_SET_CONSUMER_USAGE);
+ gralloc1_set_dimensions = (GRALLOC1_PFN_SET_DIMENSIONS)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_SET_DIMENSIONS);
+ gralloc1_set_format = (GRALLOC1_PFN_SET_FORMAT)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_SET_FORMAT);
+ gralloc1_set_producer_usage = (GRALLOC1_PFN_SET_PRODUCER_USAGE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_SET_PRODUCER_USAGE);
+ gralloc1_get_backing_store = (GRALLOC1_PFN_GET_BACKING_STORE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_BACKING_STORE);
+ gralloc1_get_consumer_usage = (GRALLOC1_PFN_GET_CONSUMER_USAGE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
+ gralloc1_get_dimensions = (GRALLOC1_PFN_GET_DIMENSIONS)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_DIMENSIONS);
+ gralloc1_get_format = (GRALLOC1_PFN_GET_FORMAT)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_FORMAT);
+ gralloc1_get_producer_usage = (GRALLOC1_PFN_GET_PRODUCER_USAGE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
+ gralloc1_get_stride = (GRALLOC1_PFN_GET_STRIDE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_STRIDE);
+ gralloc1_allocate = (GRALLOC1_PFN_ALLOCATE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_ALLOCATE);
+ gralloc1_retain = (GRALLOC1_PFN_RETAIN)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_RETAIN);
+ gralloc1_release = (GRALLOC1_PFN_RELEASE)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_RELEASE);
+ gralloc1_get_num_flex_planes = (GRALLOC1_PFN_GET_NUM_FLEX_PLANES)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
+ gralloc1_lock = (GRALLOC1_PFN_LOCK)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_LOCK);
+ gralloc1_lock_flex = (GRALLOC1_PFN_LOCK_FLEX)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_LOCK_FLEX);
+ gralloc1_unlock = (GRALLOC1_PFN_UNLOCK)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_UNLOCK);
+#ifdef GRALLOC1_PFN_SET_LAYER_COUNT
+ gralloc1_set_layer_count = (GRALLOC1_PFN_SET_LAYER_COUNT)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_SET_LAYER_COUNT);
+ gralloc1_get_layer_count = (GRALLOC1_PFN_GET_LAYER_COUNT)gralloc1_device->getFunction(gralloc1_device, GRALLOC1_FUNCTION_GET_LAYER_COUNT);
+#endif
+}
+#endif
+
+int hybris_gralloc_release(buffer_handle_t handle, int was_allocated)
+{
+ int ret = -ENOSYS;
+
+ if GRALLOC1(
+ ret = gralloc1_release(gralloc1_device, handle);
+
+ // this needs to happen if the last reference is gone, this function is
+ // only called in such cases.
+ if (!gralloc1_release_implies_delete) {
+ native_handle_close((native_handle_t*)handle);
+ native_handle_delete((native_handle_t*)handle);
+ }
+ ) else if GRALLOC0(
+ if (was_allocated) {
+ ret = gralloc0_alloc->free(gralloc0_alloc, handle);
+ } else {
+ ret = gralloc0_module->unregisterBuffer(gralloc0_module, handle);
+
+ // this needs to happen if the last reference is gone, this function is
+ // only called in such cases.
+ native_handle_close((native_handle_t*)handle);
+ native_handle_delete((native_handle_t*)handle);
+ }
+ ) else NO_GRALLOC
+
+ return ret;
+}
+
+int hybris_gralloc_retain(buffer_handle_t handle)
+{
+ int ret = -ENOSYS;
+
+ if GRALLOC1(
+ ret = gralloc1_retain(gralloc1_device, handle);
+ ) else if GRALLOC0(
+ ret = gralloc0_module->registerBuffer(gralloc0_module, handle);
+ ) else NO_GRALLOC
+
+ return ret;
+}
+
+int hybris_gralloc_allocate(int width, int height, int format, int usage, buffer_handle_t *handle_ptr, uint32_t *stride_ptr)
+{
+ int ret = -ENOSYS;
+
+ if GRALLOC1(
+ gralloc1_buffer_descriptor_t desc;
+ uint64_t producer_usage;
+ uint64_t consumer_usage;
+
+ android_convertGralloc0To1Usage(usage, &producer_usage, &consumer_usage);
+
+ // create temporary description (descriptor) of buffer to allocate
+ ret = gralloc1_create_descriptor(gralloc1_device, &desc);
+ ret |= gralloc1_set_dimensions(gralloc1_device, desc, width, height);
+ ret |= gralloc1_set_consumer_usage(gralloc1_device, desc, consumer_usage);
+ ret |= gralloc1_set_producer_usage(gralloc1_device, desc, producer_usage);
+ ret |= gralloc1_set_format(gralloc1_device, desc, format);
+
+ // actual allocation
+ ret |= gralloc1_allocate(gralloc1_device, 1, &desc, handle_ptr);
+
+ // get stride and release temporary descriptor
+ ret |= gralloc1_get_stride(gralloc1_device, *handle_ptr, stride_ptr);
+ ret |= gralloc1_destroy_descriptor(gralloc1_device, desc);
+ ) else if GRALLOC0(
+ ret = gralloc0_alloc->alloc(gralloc0_alloc,
+ width, height, format, usage,
+ handle_ptr, (int*)stride_ptr);
+ ) else NO_GRALLOC
+
+ return ret;
+}
+
+int hybris_gralloc_lock(buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr)
+{
+ int ret = -ENOSYS;
+
+ if GRALLOC1(
+ uint64_t producer_usage;
+ uint64_t consumer_usage;
+ gralloc1_rect_t access_region;
+
+ access_region.left = l;
+ access_region.top = t;
+ access_region.width = w;
+ access_region.height = h;
+
+ android_convertGralloc0To1Usage(usage, &producer_usage, &consumer_usage);
+
+ ret = gralloc1_lock(gralloc1_device, handle, producer_usage, consumer_usage, &access_region, vaddr, -1);
+ ) else if GRALLOC0(
+ ret = gralloc0_module->lock(gralloc0_module, handle, usage, l, t, w, h, vaddr);
+ ) else NO_GRALLOC
+
+ return ret;
+}
+
+int hybris_gralloc_unlock(buffer_handle_t handle)
+{
+ int ret = -ENOSYS;
+
+ if GRALLOC1(
+ int releaseFence = 0;
+ ret = gralloc1_unlock(gralloc1_device, handle, &releaseFence);
+ close(releaseFence);
+ ) else if GRALLOC0(
+ ret = gralloc0_module->unlock(gralloc0_module, handle);
+ ) else NO_GRALLOC
+
+ return ret;
+}
+
+// Legacy fbdev methods. these are not available in gralloc1 thus use old API.
+int hybris_gralloc_fbdev_format(void)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->format;
+}
+
+int hybris_gralloc_fbdev_framebuffer_count(void)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->numFramebuffers;
+}
+
+int hybris_gralloc_fbdev_setSwapInterval(int interval)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->setSwapInterval(framebuffer_device, interval);
+}
+
+int hybris_gralloc_fbdev_post(buffer_handle_t handle)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->post(framebuffer_device, handle);
+}
+
+int hybris_gralloc_fbdev_width(void)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->width;
+}
+
+int hybris_gralloc_fbdev_height(void)
+{
+ assert(framebuffer_device);
+ return framebuffer_device->height;
+}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/gralloc/libgralloc.pc.in
^
|
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=@libdir@
+includedir=@includedir@
+
+Name: hybris-gralloc
+Description: libhybris gralloc library
+Version: @VERSION@
+Requires: android-headers
+Libs: -L${libdir} -lgralloc
+Cflags: -I${includedir}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/hwc2/Makefile.am
^
|
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = \
+ libhwc2.la
+
+libhwc2_la_SOURCES = hwc2.c
+libhwc2_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
+if WANT_TRACE
+libhwc2_la_CFLAGS += -DDEBUG
+endif
+if WANT_DEBUG
+libhwc2_la_CFLAGS += -ggdb -O0
+endif
+if HAS_HWCOMPOSER2_HEADERS
+libhwc2_la_CFLAGS += \
+ -DHAS_HWCOMPOSER2_HEADERS=1
+else
+libhwc2_la_CFLAGS += \
+ -DHAS_HWCOMPOSER2_HEADERS=0
+endif
+libhwc2_la_LDFLAGS = \
+ $(top_builddir)/common/libhybris-common.la \
+ -version-info "1":"0":"0"
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libhwc2.pc
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/hwc2/hwc2.c
^
|
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 TheKit <nekit1000@gmail.com>
+ *
+ * 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.
+ */
+
+#if HAS_HWCOMPOSER2_HEADERS
+
+#include <dlfcn.h>
+#include <stddef.h>
+
+#include <hybris/common/binding.h>
+#include <hybris/hwc2/hwc2_compatibility_layer.h>
+
+#define COMPAT_LIBRARY_PATH "libhwc2_compat_layer.so"
+
+HYBRIS_LIBRARY_INITIALIZE(hwc2, COMPAT_LIBRARY_PATH);
+
+HYBRIS_IMPLEMENT_FUNCTION1(hwc2, hwc2_compat_device_t*, hwc2_compat_device_new,
+ bool);
+
+HYBRIS_IMPLEMENT_VOID_FUNCTION3(hwc2, hwc2_compat_device_register_callback,
+ hwc2_compat_device_t*, HWC2EventListener*, int);
+
+HYBRIS_IMPLEMENT_VOID_FUNCTION3(hwc2, hwc2_compat_device_on_hotplug,
+ hwc2_compat_device_t*, hwc2_display_t, bool);
+
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_compat_display_t*,
+ hwc2_compat_device_get_display_by_id,
+ hwc2_compat_device_t*,
+ hwc2_display_t);
+
+HYBRIS_IMPLEMENT_FUNCTION1(hwc2, HWC2DisplayConfig*,
+ hwc2_compat_display_get_active_config,
+ hwc2_compat_display_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION1(hwc2, hwc2_error_t,
+ hwc2_compat_display_accept_changes,
+ hwc2_compat_display_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION1(hwc2, hwc2_compat_layer_t*,
+ hwc2_compat_display_create_layer,
+ hwc2_compat_display_t*);
+
+HYBRIS_IMPLEMENT_VOID_FUNCTION2(hwc2, hwc2_compat_display_destroy_layer,
+ hwc2_compat_display_t*, hwc2_compat_layer_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t,
+ hwc2_compat_display_get_release_fences,
+ hwc2_compat_display_t*, hwc2_compat_out_fences_t**);
+
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_display_present,
+ hwc2_compat_display_t*, int32_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION5(hwc2, hwc2_error_t, hwc2_compat_display_set_client_target,
+ hwc2_compat_display_t*, uint32_t,
+ ANativeWindowBuffer_t*, int32_t,
+ android_dataspace_t);
+
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_display_set_power_mode,
+ hwc2_compat_display_t*, int);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_display_set_vsync_enabled,
+ hwc2_compat_display_t*, int);
+
+HYBRIS_IMPLEMENT_FUNCTION3(hwc2, hwc2_error_t, hwc2_compat_display_validate,
+ hwc2_compat_display_t*, uint32_t*, uint32_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION5(hwc2, hwc2_error_t, hwc2_compat_display_present_or_validate,
+ hwc2_compat_display_t*, uint32_t*, uint32_t*,
+ int32_t*, uint32_t*);
+
+HYBRIS_IMPLEMENT_FUNCTION4(hwc2, hwc2_error_t, hwc2_compat_layer_set_buffer,
+ hwc2_compat_layer_t*, uint32_t,
+ ANativeWindowBuffer_t*, int32_t);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_blend_mode,
+ hwc2_compat_layer_t*, int);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_color,
+ hwc2_compat_layer_t*, hwc_color_t);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_composition_type,
+ hwc2_compat_layer_t*, int);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_dataspace,
+ hwc2_compat_layer_t*, android_dataspace_t);
+HYBRIS_IMPLEMENT_FUNCTION5(hwc2, hwc2_error_t, hwc2_compat_layer_set_display_frame,
+ hwc2_compat_layer_t*, int32_t, int32_t,
+ int32_t, int32_t);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_plane_alpha,
+ hwc2_compat_layer_t*, float);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_sideband_stream,
+ hwc2_compat_layer_t*, native_handle_t*);
+HYBRIS_IMPLEMENT_FUNCTION5(hwc2, hwc2_error_t, hwc2_compat_layer_set_source_crop,
+ hwc2_compat_layer_t*, float, float, float, float);
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, hwc2_error_t, hwc2_compat_layer_set_transform,
+ hwc2_compat_layer_t*, int);
+HYBRIS_IMPLEMENT_FUNCTION5(hwc2, hwc2_error_t, hwc2_compat_layer_set_visible_region,
+ hwc2_compat_layer_t*, int32_t, int32_t,
+ int32_t, int32_t);
+
+HYBRIS_IMPLEMENT_FUNCTION2(hwc2, int32_t, hwc2_compat_out_fences_get_fence,
+ hwc2_compat_out_fences_t*, hwc2_compat_layer_t*);
+HYBRIS_IMPLEMENT_VOID_FUNCTION1(hwc2, hwc2_compat_out_fences_destroy,
+ hwc2_compat_out_fences_t*);
+
+#endif
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/hwc2/libhwc2.pc.in
^
|
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=@libdir@
+includedir=@includedir@
+
+Name: hybris-hwcomposer2
+Description: libhybris hwcomposer2 library
+Version: @VERSION@
+Libs: -L${libdir} -lhybris-common -lhwc2
+Cflags: -I${includedir}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/EGL/egl.h
^
|
@@ -41,6 +41,8 @@
/* EGL Types */
/* EGLint is defined in eglplatform.h */
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
@@ -48,6 +50,8 @@
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
+typedef void *EGLSync;
+typedef void *EGLImage;
/* EGL Versioning */
#define EGL_VERSION_1_0 1
@@ -55,6 +59,7 @@
#define EGL_VERSION_1_2 1
#define EGL_VERSION_1_3 1
#define EGL_VERSION_1_4 1
+#define EGL_VERSION_1_5 1
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
* enums are assigned unique values starting at 0x3000.
@@ -242,6 +247,50 @@
* a bug in Khronos Bugzilla against task "Registry".
*/
+/* EGL 1.5 tokens */
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
/* EGL Functions */
@@ -313,6 +362,18 @@
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
+/* EGL 1.5 */
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync(EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage(EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags);
+
/* This is a generic function pointer type, whose name indicates it must
* be cast to the proper type *and calling convention* before use.
*/
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/Makefile.am
^
|
@@ -47,6 +47,10 @@
surface_flingerinclude_HEADERS = \
hybris/surface_flinger/surface_flinger_compatibility_layer.h
+hwc2includedir = $(includedir)/hybris/hwc2
+hwc2include_HEADERS = \
+ hybris/hwc2/hwc2_compatibility_layer.h
+
inputincludedir = $(includedir)/hybris/input
inputinclude_HEADERS = \
hybris/input/input_stack_compatibility_layer_codes_key.h \
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/camera/camera_compatibility_layer_configuration_translator.h
^
|
@@ -28,6 +28,8 @@
extern "C" {
#endif
+#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
+
static const char* effect_modes[] =
{
android::CameraParameters::EFFECT_NONE,
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/common/binding.h
^
|
@@ -28,7 +28,7 @@
void *android_dlopen(const char *filename, int flag);
void *android_dlsym(void *name, const char *symbol);
int android_dlclose(void *handle);
-const char *android_dlerror(void);
+char *android_dlerror(void);
int android_dladdr(const void *addr, void *info);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/common/dlfcn.h
^
|
@@ -25,7 +25,7 @@
void *hybris_dlopen(const char *filename, int flag);
void *hybris_dlsym(void *handle, const char *symbol);
int hybris_dlclose(void *handle);
-const char *hybris_dlerror(void);
+char *hybris_dlerror(void);
#ifdef __cplusplus
}
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/gralloc/gralloc.h
^
|
@@ -0,0 +1,36 @@
+#ifndef hybris_gralloc_header_include_guard__
+#define hybris_gralloc_header_include_guard__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// for usage definitions and so on
+#if HAS_GRALLOC1_HEADER
+#include <hardware/gralloc1.h>
+#endif
+#include <hardware/gralloc.h>
+
+#include <cutils/native_handle.h>
+
+void hybris_gralloc_deinitialize(void);
+void hybris_gralloc_initialize(int framebuffer);
+void hybris_gralloc_deinitialize(void);
+int hybris_gralloc_release(buffer_handle_t handle, int was_allocated);
+int hybris_gralloc_retain(buffer_handle_t handle);
+int hybris_gralloc_allocate(int width, int height, int format, int usage, buffer_handle_t *handle, uint32_t *stride);
+int hybris_gralloc_lock(buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr);
+int hybris_gralloc_unlock(buffer_handle_t handle);
+int hybris_gralloc_fbdev_format(void);
+int hybris_gralloc_fbdev_framebuffer_count(void);
+int hybris_gralloc_fbdev_setSwapInterval(int interval);
+int hybris_gralloc_fbdev_post(buffer_handle_t handle);
+int hybris_gralloc_fbdev_width(void);
+int hybris_gralloc_fbdev_height(void);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/grallocusage/GrallocUsageConversion.h
^
|
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#ifndef ANDROID_GRALLOCUSAGE_GRALLOC_USAGE_CONVERSION_H
+#define ANDROID_GRALLOCUSAGE_GRALLOC_USAGE_CONVERSION_H 1
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Conversion functions are out-of-line so that users don't have to be exposed to
+// android/hardware/graphics/allocator/2.0/types.h and link against
+// android.hardware.graphics.allocator@2.0 to get that in their search path.
+
+// Convert a 32-bit gralloc0 usage mask to a producer/consumer pair of 64-bit usage masks as used
+// by android.hardware.graphics.allocator@2.0 (and gralloc1). This conversion properly handles the
+// mismatch between a.h.g.allocator@2.0's CPU_{READ,WRITE}_OFTEN and gralloc0's
+// SW_{READ,WRITE}_OFTEN.
+void android_convertGralloc0To1Usage(int32_t usage, uint64_t* producerUsage,
+ uint64_t* consumerUsage);
+
+// Convert a producer/consumer pair of 64-bit usage masks as used by
+// android.hardware.graphics.allocator@2.0 (and gralloc1) to a 32-bit gralloc0 usage mask. This
+// conversion properly handles the mismatch between a.h.g.allocator@2.0's CPU_{READ,WRITE}_OFTEN
+// and gralloc0's SW_{READ,WRITE}_OFTEN.
+int32_t android_convertGralloc1To0Usage(uint64_t producerUsage, uint64_t consumerUsage);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANDROID_GRALLOCUSAGE_GRALLOC_USAGE_CONVERSION_H
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/hwc2/hwc2_compatibility_layer.h
^
|
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 TheKit <nekit1000@gmail.com>
+ *
+ * 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.
+ */
+
+#ifndef HWC2_COMPATIBILITY_LAYER_H_
+#define HWC2_COMPATIBILITY_LAYER_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <hardware/hwcomposer2.h>
+#include <system/graphics.h>
+#include <system/window.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ struct HWC2EventListener;
+ typedef struct HWC2EventListener HWC2EventListener;
+
+ typedef void (*on_vsync_received_callback)(HWC2EventListener* self,
+ int32_t sequenceId, hwc2_display_t display,
+ int64_t timestamp);
+ typedef void (*on_hotplug_received_callback)(HWC2EventListener* self,
+ int32_t sequenceId, hwc2_display_t display,
+ bool connected, bool primaryDisplay);
+ typedef void (*on_refresh_received_callback)(HWC2EventListener* self,
+ int32_t sequenceId, hwc2_display_t display);
+
+ struct HWC2EventListener
+ {
+ on_vsync_received_callback on_vsync_received;
+ on_hotplug_received_callback on_hotplug_received;
+ on_refresh_received_callback on_refresh_received;
+ };
+
+ typedef struct HWC2DisplayConfig {
+ hwc2_config_t id;
+ hwc2_display_t display;
+ int32_t width;
+ int32_t height;
+ int64_t vsyncPeriod;
+ float dpiX;
+ float dpiY;
+ } HWC2DisplayConfig;
+
+ struct hwc2_compat_device;
+ typedef struct hwc2_compat_device hwc2_compat_device_t;
+
+ struct hwc2_compat_display;
+ typedef struct hwc2_compat_display hwc2_compat_display_t;
+
+ struct hwc2_compat_layer;
+ typedef struct hwc2_compat_layer hwc2_compat_layer_t;
+
+ struct hwc2_compat_out_fences;
+ typedef struct hwc2_compat_out_fences hwc2_compat_out_fences_t;
+
+ hwc2_compat_device_t* hwc2_compat_device_new(bool);
+ void hwc2_compat_device_register_callback(hwc2_compat_device_t* device,
+ HWC2EventListener* listener,
+ int composerSequenceId);
+
+ void hwc2_compat_device_on_hotplug(hwc2_compat_device_t* device,
+ hwc2_display_t displayId,
+ bool connected);
+
+ hwc2_compat_display_t* hwc2_compat_device_get_display_by_id(
+ hwc2_compat_device_t* device,
+ hwc2_display_t id);
+
+ HWC2DisplayConfig* hwc2_compat_display_get_active_config(
+ hwc2_compat_display_t* display);
+
+ hwc2_error_t hwc2_compat_display_accept_changes(hwc2_compat_display_t* display);
+ hwc2_compat_layer_t* hwc2_compat_display_create_layer(hwc2_compat_display_t*
+ display);
+ void hwc2_compat_display_destroy_layer(hwc2_compat_display_t* display,
+ hwc2_compat_layer_t* layer);
+
+ hwc2_error_t hwc2_compat_display_get_release_fences(
+ hwc2_compat_display_t* display,
+ hwc2_compat_out_fences_t** outFences);
+
+ hwc2_error_t hwc2_compat_display_present(hwc2_compat_display_t* display,
+ int32_t* outPresentFence);
+
+ hwc2_error_t hwc2_compat_display_set_client_target(hwc2_compat_display_t* display,
+ uint32_t slot,
+ struct ANativeWindowBuffer* buffer,
+ const int32_t acquireFenceFd,
+ android_dataspace_t dataspace);
+
+ hwc2_error_t hwc2_compat_display_set_power_mode(hwc2_compat_display_t* display,
+ int mode);
+ hwc2_error_t hwc2_compat_display_set_vsync_enabled(hwc2_compat_display_t* display,
+ int enabled);
+
+ hwc2_error_t hwc2_compat_display_validate(hwc2_compat_display_t* display,
+ uint32_t* outNumTypes,
+ uint32_t* outNumRequests);
+
+ hwc2_error_t hwc2_compat_display_present_or_validate(hwc2_compat_display_t* display,
+ uint32_t* outNumTypes,
+ uint32_t* outNumRequests,
+ int32_t* outPresentFence,
+ uint32_t* state);
+
+ hwc2_error_t hwc2_compat_layer_set_buffer(hwc2_compat_layer_t* layer,
+ uint32_t slot,
+ struct ANativeWindowBuffer* buffer,
+ const int32_t acquireFenceFd);
+ hwc2_error_t hwc2_compat_layer_set_blend_mode(hwc2_compat_layer_t* layer, int mode);
+ hwc2_error_t hwc2_compat_layer_set_color(hwc2_compat_layer_t* layer,
+ hwc_color_t color);
+ hwc2_error_t hwc2_compat_layer_set_composition_type(hwc2_compat_layer_t* layer,
+ int type);
+ hwc2_error_t hwc2_compat_layer_set_dataspace(hwc2_compat_layer_t* layer,
+ android_dataspace_t dataspace);
+ hwc2_error_t hwc2_compat_layer_set_display_frame(hwc2_compat_layer_t* layer,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom);
+ hwc2_error_t hwc2_compat_layer_set_plane_alpha(hwc2_compat_layer_t* layer,
+ float alpha);
+ hwc2_error_t hwc2_compat_layer_set_sideband_stream(hwc2_compat_layer_t* layer,
+ native_handle_t* stream);
+ hwc2_error_t hwc2_compat_layer_set_source_crop(hwc2_compat_layer_t* layer,
+ float left, float top,
+ float right, float bottom);
+ hwc2_error_t hwc2_compat_layer_set_transform(hwc2_compat_layer_t* layer,
+ int transform);
+ hwc2_error_t hwc2_compat_layer_set_visible_region(hwc2_compat_layer_t* layer,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom);
+
+ int32_t hwc2_compat_out_fences_get_fence(hwc2_compat_out_fences_t* fences,
+ hwc2_compat_layer_t* layer);
+ void hwc2_compat_out_fences_destroy(hwc2_compat_out_fences_t* fences);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HWC2_COMPATIBILITY_LAYER_H_
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/internal/camera_control.h
^
|
@@ -19,6 +19,9 @@
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
+#if ANDROID_VERSION_MAJOR>=7
+#include <camera/android/hardware/ICamera.h>
+#endif
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
#include <gui/SurfaceTexture.h>
#else
@@ -69,6 +72,9 @@
nsecs_t timestamp,
int32_t msg_type,
const android::sp<android::IMemory>& data);
+#if ANDROID_VERSION_MAJOR >= 7
+ void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
+#endif
};
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/include/hybris/properties/properties.h
^
|
@@ -33,6 +33,9 @@
/* Only SETPROP is defined by Android, for GETPROP and LISTPROP to work
* an extended Android init service needs to be in place */
+/* Starting from android 8 getprop and listprop are handled in libhybris
+ * via bionic, thus the init service does not need to be patched for this
+ * anymore */
#define PROP_MSG_SETPROP 1
#define PROP_MSG_GETPROP 2
#define PROP_MSG_LISTPROP 3
@@ -41,15 +44,9 @@
extern "C" {
#endif
- typedef struct prop_msg_s {
- unsigned cmd;
- char name[PROP_NAME_MAX];
- char value[PROP_VALUE_MAX];
- } prop_msg_t;
-
- int property_set(const char *key, const char *value);
- int property_get(const char *key, char *value, const char *default_value);
- int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);
+int property_set(const char *key, const char *value);
+int property_get(const char *key, char *value, const char *default_value);
+int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);
#ifdef __cplusplus
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/libnfc_ndef_nxp/Makefile.am
^
|
@@ -7,6 +7,14 @@
$(ANDROID_HEADERS_CFLAGS) \
-Wno-error=unused-function
+if HAS_LIBNFC_NXP_HEADERS
+libnfc_ndef_nxp_la_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=1
+else
+libnfc_ndef_nxp_la_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=0
+endif
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnfc_ndef_nxp.pc
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/libnfc_ndef_nxp/libnfc_ndef_nxp.c
^
|
@@ -17,10 +17,11 @@
*/
/**
- * Bindings generated using:
- * https://github.com/thp/libhybris-nfc-wrapper-generator
+ * Bindings generated using scripts in: utils/generate_nfc
**/
+#if HAS_LIBNFC_NXP_HEADERS
+
#include <libnfc-nxp/phNfcStatus.h>
#include <libnfc-nxp/phNfcTypes.h>
#include <libnfc-nxp/phNfcIoctlCode.h>
@@ -41,3 +42,5 @@
HYBRIS_IMPLEMENT_FUNCTION2(libnfc_ndef_so, NFCSTATUS, phFriNfc_NdefRecord_Parse, phFriNfc_NdefRecord_t *, uint8_t *);
HYBRIS_IMPLEMENT_FUNCTION4(libnfc_ndef_so, NFCSTATUS, phFriNfc_NdefRecord_Generate, phFriNfc_NdefRecord_t *, uint8_t *, uint32_t, uint32_t *);
/* XXX No prototype for exported symbol: __on_dlclose */
+#endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/libnfc_nxp/Makefile.am
^
|
@@ -7,6 +7,14 @@
$(ANDROID_HEADERS_CFLAGS) \
-Wno-error=unused-function
+if HAS_LIBNFC_NXP_HEADERS
+libnfc_nxp_la_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=1
+else
+libnfc_nxp_la_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=0
+endif
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnfc_nxp.pc
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/libnfc_nxp/libnfc_nxp.c
^
|
@@ -17,10 +17,11 @@
*/
/**
- * Bindings generated using:
- * https://github.com/thp/libhybris-nfc-wrapper-generator
+ * Bindings generated using scripts in: utils/generate_nfc
**/
+#if HAS_LIBNFC_NXP_HEADERS
+
#include <android-config.h>
#include <libnfc-nxp/phNfcTypes.h>
@@ -594,3 +595,5 @@
HYBRIS_IMPLEMENT_FUNCTION3(libnfc_so, int, phDal4Nfc_msgctl, int, int, void *);
HYBRIS_IMPLEMENT_FUNCTION5(libnfc_so, int, phDal4Nfc_msgrcv, int, void *, size_t, long, int);
/* XXX No prototype for exported symbol: __on_dlclose */
+#endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/libsync/sync.c
^
|
@@ -21,22 +21,119 @@
#include <string.h>
#include <stdlib.h>
+#include <android-version.h>
+
+#if (ANDROID_VERSION_MAJOR <= 7)
#include <linux/sync.h>
#include <linux/sw_sync.h>
+#else
+#include <sync/sync.h>
+#endif
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#if (ANDROID_VERSION_MAJOR >= 8)
+#include <errno.h>
+#include <linux/types.h>
+#include <poll.h>
+#include <../common/n/bionic/libc/include/stdatomic.h>
+
+enum uapi_version {
+ UAPI_UNKNOWN,
+ UAPI_MODERN,
+ UAPI_LEGACY
+};
+static atomic_int g_uapi_version = ATOMIC_VAR_INIT(UAPI_UNKNOWN);
+
+/* Legacy Sync API */
+
+struct sync_legacy_merge_data {
+ int32_t fd2;
+ char name[32];
+ int32_t fence;
+};
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
+ * new fence's fd in sync_merge_data.fence
+ *
+ * This is the legacy version of the Sync API before the de-stage that happened
+ * on Linux kernel 4.7.
+ */
+#define SYNC_IOC_LEGACY_MERGE _IOWR(SYNC_IOC_MAGIC, 1, \
+ struct sync_legacy_merge_data)
+/**
+ * DOC: SYNC_IOC_LEGACY_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len. On return, len is
+ * updated to reflect the total size of the sync_fence_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
+ *
+ * This is the legacy version of the Sync API before the de-stage that happened
+ * on Linux kernel 4.7.
+ */
+
+#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\
+ struct sync_fence_info_data)
+
+/* SW Sync API */
+struct sw_sync_create_fence_data {
+ __u32 value;
+ char name[32];
+ __s32 fence;
+};
+
+#define SW_SYNC_IOC_MAGIC 'W'
+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0, struct sw_sync_create_fence_data)
+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
+
+
+
+#endif //(ANDROID_VERSION_MAJOR >= 8)
+
extern size_t strlcpy(char *dst, const char *src, size_t siz);
int sync_wait(int fd, int timeout)
{
+#if (ANDROID_VERSION_MAJOR <= 7)
__s32 to = timeout;
return ioctl(fd, SYNC_IOC_WAIT, &to);
+#else
+ struct pollfd fds;
+ int ret;
+ if (fd < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ fds.fd = fd;
+ fds.events = POLLIN;
+ do {
+ ret = poll(&fds, 1, timeout);
+ if (ret > 0) {
+ if (fds.revents & (POLLERR | POLLNVAL)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+ } else if (ret == 0) {
+ errno = ETIME;
+ return -1;
+ }
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+ return ret;
+#endif
}
+#if (ANDROID_VERSION_MAJOR <= 7)
int sync_merge(const char *name, int fd1, int fd2)
{
struct sync_merge_data data;
@@ -51,7 +148,64 @@
return data.fence;
}
+#else
+static int legacy_sync_merge(const char *name, int fd1, int fd2)
+{
+ struct sync_legacy_merge_data data;
+ int ret;
+
+ data.fd2 = fd2;
+ strlcpy(data.name, name, sizeof(data.name));
+ ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &data);
+ if (ret < 0)
+ return ret;
+ return data.fence;
+}
+
+static int modern_sync_merge(const char *name, int fd1, int fd2)
+{
+ struct sync_merge_data data;
+ int ret;
+
+ data.fd2 = fd2;
+ strlcpy(data.name, name, sizeof(data.name));
+ data.flags = 0;
+ data.pad = 0;
+
+ ret = ioctl(fd1, SYNC_IOC_MERGE, &data);
+ if (ret < 0)
+ return ret;
+ return data.fence;
+}
+
+int sync_merge(const char *name, int fd1, int fd2)
+{
+ int uapi;
+ int ret;
+ uapi = atomic_load_explicit(&g_uapi_version, memory_order_acquire);
+
+ if (uapi == UAPI_MODERN || uapi == UAPI_UNKNOWN) {
+ ret = modern_sync_merge(name, fd1, fd2);
+ if (ret >= 0 || errno != ENOTTY) {
+ if (ret >= 0 && uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_MODERN,
+ memory_order_release);
+ }
+ return ret;
+ }
+ }
+
+ ret = legacy_sync_merge(name, fd1, fd2);
+ if (ret >= 0 && uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_LEGACY,
+ memory_order_release);
+ }
+ return ret;
+}
+#endif
+
+#if (ANDROID_VERSION_MAJOR <= 7)
struct sync_fence_info_data *sync_fence_info(int fd)
{
struct sync_fence_info_data *info;
@@ -70,6 +224,188 @@
return info;
}
+#else
+static struct sync_fence_info_data *legacy_sync_fence_info(int fd)
+{
+ struct sync_fence_info_data *legacy_info;
+ int err;
+
+ legacy_info = malloc(4096);
+ if (legacy_info == NULL)
+ return NULL;
+
+ legacy_info->len = 4096;
+ err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, legacy_info);
+ if (err < 0) {
+ free(legacy_info);
+ return NULL;
+ }
+ return legacy_info;
+}
+
+static struct sync_file_info *modern_sync_file_info(int fd)
+{
+ struct sync_file_info local_info;
+ struct sync_file_info *info;
+ int err;
+
+ memset(&local_info, 0, sizeof(local_info));
+ err = ioctl(fd, SYNC_IOC_FILE_INFO, &local_info);
+ if (err < 0)
+ return NULL;
+
+ info = calloc(1, sizeof(struct sync_file_info) +
+ local_info.num_fences * sizeof(struct sync_fence_info));
+ if (!info)
+ return NULL;
+ info->sync_fence_info = (__u64)(uintptr_t)(info + 1);
+
+ err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
+ if (err < 0) {
+ free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+static struct sync_fence_info_data *sync_file_info_to_legacy_fence_info(
+ const struct sync_file_info *info)
+{
+ struct sync_fence_info_data *legacy_info;
+ struct sync_pt_info *legacy_pt_info;
+ const struct sync_fence_info *fence_info = sync_get_fence_info(info);
+ const uint32_t num_fences = info->num_fences;
+
+ legacy_info = malloc(4096);
+ if (legacy_info == NULL)
+ return NULL;
+ legacy_info->len = sizeof(*legacy_info) +
+ num_fences * sizeof(struct sync_pt_info);
+ strlcpy(legacy_info->name, info->name, sizeof(legacy_info->name));
+ legacy_info->status = info->status;
+
+ legacy_pt_info = (struct sync_pt_info *)legacy_info->pt_info;
+ uint32_t i;
+ for (i = 0; i < num_fences; i++) {
+ legacy_pt_info[i].len = sizeof(*legacy_pt_info);
+ strlcpy(legacy_pt_info[i].obj_name, fence_info[i].obj_name,
+ sizeof(legacy_pt_info->obj_name));
+ strlcpy(legacy_pt_info[i].driver_name, fence_info[i].driver_name,
+ sizeof(legacy_pt_info->driver_name));
+ legacy_pt_info[i].status = fence_info[i].status;
+ legacy_pt_info[i].timestamp_ns = fence_info[i].timestamp_ns;
+ }
+
+ return legacy_info;
+}
+
+static struct sync_file_info* legacy_fence_info_to_sync_file_info(
+ struct sync_fence_info_data *legacy_info)
+{
+ struct sync_file_info *info;
+ struct sync_pt_info *pt;
+ struct sync_fence_info *fence;
+ size_t num_fences;
+
+ pt = NULL;
+ num_fences = 0;
+ while ((pt = sync_pt_info(legacy_info, pt)) != NULL)
+ num_fences++;
+
+ info = calloc(1, sizeof(struct sync_file_info) +
+ num_fences * sizeof(struct sync_fence_info));
+ if (!info) {
+ free(legacy_info);
+ return NULL;
+ }
+ info->sync_fence_info = (__u64)(uintptr_t)(info + 1);
+
+ strlcpy(info->name, legacy_info->name, sizeof(info->name));
+ info->status = legacy_info->status;
+ info->num_fences = num_fences;
+
+ pt = NULL;
+ fence = sync_get_fence_info(info);
+ while ((pt = sync_pt_info(legacy_info, pt)) != NULL) {
+ strlcpy(fence->obj_name, pt->obj_name, sizeof(fence->obj_name));
+ strlcpy(fence->driver_name, pt->driver_name,
+ sizeof(fence->driver_name));
+ fence->status = pt->status;
+ fence->timestamp_ns = pt->timestamp_ns;
+ fence++;
+ }
+
+ return info;
+}
+
+struct sync_fence_info_data *sync_fence_info(int fd)
+{
+ struct sync_fence_info_data *legacy_info;
+ int uapi;
+
+ uapi = atomic_load_explicit(&g_uapi_version, memory_order_acquire);
+
+ if (uapi == UAPI_LEGACY || uapi == UAPI_UNKNOWN) {
+ legacy_info = legacy_sync_fence_info(fd);
+ if (legacy_info || errno != ENOTTY) {
+ if (legacy_info && uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_LEGACY,
+ memory_order_release);
+ }
+ return legacy_info;
+ }
+ }
+
+ struct sync_file_info* file_info;
+ file_info = modern_sync_file_info(fd);
+ if (!file_info)
+ return NULL;
+ if (uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_MODERN,
+ memory_order_release);
+ }
+ legacy_info = sync_file_info_to_legacy_fence_info(file_info);
+ sync_file_info_free(file_info);
+ return legacy_info;
+}
+
+struct sync_file_info* sync_file_info(int32_t fd)
+{
+ struct sync_file_info *info;
+ int uapi;
+
+ uapi = atomic_load_explicit(&g_uapi_version, memory_order_acquire);
+
+ if (uapi == UAPI_MODERN || uapi == UAPI_UNKNOWN) {
+ info = modern_sync_file_info(fd);
+ if (info || errno != ENOTTY) {
+ if (info && uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_MODERN,
+ memory_order_release);
+ }
+ return info;
+ }
+ }
+
+ struct sync_fence_info_data *legacy_info;
+ legacy_info = legacy_sync_fence_info(fd);
+ if (!legacy_info)
+ return NULL;
+ if (uapi == UAPI_UNKNOWN) {
+ atomic_store_explicit(&g_uapi_version, UAPI_LEGACY,
+ memory_order_release);
+ }
+ info = legacy_fence_info_to_sync_file_info(legacy_info);
+ sync_fence_info_free(legacy_info);
+ return info;
+}
+
+void sync_file_info_free(struct sync_file_info *info)
+{
+ free(info);
+}
+#endif
struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info,
struct sync_pt_info *itr)
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/properties/Makefile.am
^
|
@@ -1,19 +1,20 @@
lib_LTLIBRARIES = \
libandroid-properties.la
-libandroid_properties_la_SOURCES = properties.c cache.c
-libandroid_properties_la_CFLAGS = -I$(top_srcdir)/include $(ANDROID_HEADERS_CFLAGS)
-if WANT_RUNTIME_PROPERTY_CACHE
-libandroid_properties_la_SOURCES += runtime_cache.c
-else
-libandroid_properties_la_CFLAGS += -DNO_RUNTIME_PROPERTY_CACHE
-endif
+libandroid_properties_la_SOURCES = hybris_properties.c
if WANT_DEBUG
-libandroid_properties_la_CFLAGS += -ggdb -O0
+libandroid_properties_la_CFLAGS = -ggdb -O0
+else
+libandroid_properties_la_CFLAGS =
endif
+
+libandroid_properties_la_CFLAGS += -I$(top_srcdir)/include
+
libandroid_properties_la_LDFLAGS = \
+ $(top_srcdir)/common/libhybris-common.la \
-version-info "1":"0":"0"
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libandroid-properties.pc
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/properties/hybris_properties.c
^
|
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 Jolla Ltd. <franz.haider@jolla.com>
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#include <hybris/common/binding.h>
+
+static void *libcutils = NULL;
+
+// These may point to the libhybris implementation or to the bionic implementation, depending on the linker being used.
+static int (*bionic_property_list)(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie) = NULL;
+static int (*bionic_property_get)(const char *key, char *value, const char *default_value) = NULL;
+static int (*bionic_property_set)(const char *key, const char *value) = NULL;
+
+static void unload_libcutils(void)
+{
+ if (libcutils) {
+ android_dlclose(libcutils);
+ }
+}
+
+#define PROPERTY_DLSYM(func) {*(void **)(&bionic_##func) = (void*)android_dlsym(libcutils, #func); \
+ if (!bionic_##func) { \
+ fprintf(stderr, "failed to load " #func " from bionic libcutils\n"); \
+ abort(); \
+ }}
+
+static void ensure_bionic_properties_initialized(void)
+{
+ if (!libcutils) {
+ libcutils = android_dlopen("libcutils.so", RTLD_LAZY);
+ if (libcutils) {
+ PROPERTY_DLSYM(property_get);
+ PROPERTY_DLSYM(property_set);
+ PROPERTY_DLSYM(property_list);
+ atexit(unload_libcutils);
+ } else {
+ fprintf(stderr, "failed to load bionic libc.so\n");
+ abort();
+ }
+ }
+}
+
+int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie)
+{
+ ensure_bionic_properties_initialized();
+
+ return bionic_property_list(propfn, cookie);
+}
+
+int property_get(const char *key, char *value, const char *default_value)
+{
+ ensure_bionic_properties_initialized();
+
+ return bionic_property_get(key, value, default_value);
+}
+
+int property_set(const char *key, const char *value)
+{
+ ensure_bionic_properties_initialized();
+
+ return bionic_property_set(key, value);
+}
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/Makefile.am
^
|
@@ -13,34 +13,11 @@
test_recorder \
test_gps \
test_opencl \
- test_wifi
+ test_wifi \
+ test_hwc2 \
+ test_hwcomposer \
+ test_nfc
-if HAS_ANDROID_4_2_0
-bin_PROGRAMS += test_hwcomposer
-endif
-
-if HAS_ANDROID_5_0_0
-bin_PROGRAMS += test_hwcomposer
-endif
-
-
-if HAS_LIBNFC_NXP_HEADERS
-# test_nfc depends on NFC hardware HAL interface, which is only
-# available until Android API level 15 (v4.0.3, v4.0.4).
-if HAS_ANDROID_4_0_3
-bin_PROGRAMS += test_nfc
-else
-if HAS_ANDROID_4_1_0
-bin_PROGRAMS += test_nfc
-else
-if HAS_ANDROID_5_0_0
-bin_PROGRAMS += test_nfc
-endif
-endif
-endif
-endif
-
-bin_PROGRAMS += test_audio
test_audio_SOURCES = test_audio.c
test_audio_CFLAGS = \
-I$(top_srcdir)/include \
@@ -98,13 +75,24 @@
test_hwcomposer_LDADD = \
-lm \
$(top_builddir)/common/libhybris-common.la \
- $(top_builddir)/egl/platforms/hwcomposer/libhybris-hwcomposerwindow.la \
$(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
$(top_builddir)/egl/libEGL.la \
$(top_builddir)/glesv2/libGLESv2.la \
- $(top_builddir)/libsync/libsync.la \
$(top_builddir)/hardware/libhardware.la
+
+if HAS_ANDROID_4_2_0
+test_hwcomposer_LDADD += \
+ $(top_builddir)/libsync/libsync.la \
+ $(top_builddir)/egl/platforms/hwcomposer/libhybris-hwcomposerwindow.la
+else
+if HAS_ANDROID_5_0_0
+test_hwcomposer_LDADD += \
+ $(top_builddir)/libsync/libsync.la \
+ $(top_builddir)/egl/platforms/hwcomposer/libhybris-hwcomposerwindow.la
+endif
+endif
+
test_sensors_SOURCES = test_sensors.c
test_sensors_CFLAGS = \
-I$(top_srcdir)/include \
@@ -152,13 +140,14 @@
test_camera_CFLAGS = \
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS)
-
test_camera_LDADD = \
$(top_builddir)/common/libhybris-common.la \
$(top_builddir)/egl/libEGL.la \
$(top_builddir)/glesv2/libGLESv2.la \
$(top_builddir)/camera/libcamera.la \
- $(top_builddir)/input/libis.la
+ $(top_builddir)/input/libis.la \
+ $(top_builddir)/egl/platforms/common/libwayland-egl.la \
+ $(WAYLAND_CLIENT_LIBS)
test_media_SOURCES = test_media.c
test_media_CFLAGS = \
@@ -196,6 +185,15 @@
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS) \
-Wno-error=unused-function
+
+if HAS_LIBNFC_NXP_HEADERS
+test_nfc_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=1
+else
+test_nfc_CFLAGS += \
+ -DHAS_LIBNFC_NXP_HEADERS=0
+endif
+
test_nfc_LDFLAGS = -pthread
test_nfc_LDADD = \
$(top_builddir)/common/libhybris-common.la \
@@ -206,6 +204,11 @@
test_vibrator_CFLAGS = \
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS)
+if HAS_VIBRATOR_HEADER
+test_vibrator_CFLAGS += -DHAS_VIBRATOR_HEADER=1
+else
+test_vibrator_CFLAGS += -DHAS_VIBRATOR_HEADER=0
+endif
test_vibrator_LDADD = \
$(top_builddir)/common/libhybris-common.la \
$(top_builddir)/hardware/libhardware.la \
@@ -215,6 +218,15 @@
test_wifi_CFLAGS = \
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS)
+
+if HAS_WIFI_LEGACY_HEADERS
+test_wifi_CFLAGS += \
+ -DHAS_WIFI_LEGACY_HEADERS=1
+else
+test_wifi_CFLAGS += \
+ -DHAS_WIFI_LEGACY_HEADERS=0
+endif
+
test_wifi_LDADD = \
$(top_builddir)/wifi/libwifi.la
@@ -226,3 +238,33 @@
$(top_builddir)/common/libhybris-common.la \
$(top_builddir)/opencl/libOpenCL.la
+test_hwc2_SOURCES = test_hwc2.cpp
+test_hwc2_CXXFLAGS = \
+ -I$(top_srcdir)/include \
+ $(ANDROID_HEADERS_CFLAGS) \
+ -I$(top_srcdir)/common \
+ -I$(top_srcdir)/egl/platforms/common \
+ -I$(top_srcdir)/egl/platforms/hwcomposer \
+ -I$(top_srcdir)/libsync \
+ -std=gnu++11
+
+if HAS_HWCOMPOSER2_HEADERS
+test_hwc2_CXXFLAGS += \
+ -DHAS_HWCOMPOSER2_HEADERS=1
+else
+test_hwc2_CXXFLAGS += \
+ -DHAS_HWCOMPOSER2_HEADERS=0
+endif
+
+if HAS_ANDROID_7_0_0
+test_hwc2_LDADD = \
+ -lm \
+ $(top_builddir)/common/libhybris-common.la \
+ $(top_builddir)/egl/platforms/hwcomposer/libhybris-hwcomposerwindow.la \
+ $(top_builddir)/egl/platforms/common/libhybris-eglplatformcommon.la \
+ $(top_builddir)/egl/libEGL.la \
+ $(top_builddir)/glesv2/libGLESv2.la \
+ $(top_builddir)/libsync/libsync.la \
+ $(top_builddir)/hwc2/libhwc2.la
+endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_camera.c
^
|
@@ -17,6 +17,11 @@
#include "config.h"
+#include <wayland-client.h>
+#include <wayland-server.h>
+#include <wayland-client-protocol.h>
+#include <wayland-egl.h>
+
#include <hybris/camera/camera_compatibility_layer.h>
#include <hybris/camera/camera_compatibility_layer_capabilities.h>
@@ -286,6 +291,70 @@
return program;
}
+struct wl_display *wldisplay = NULL;
+struct wl_compositor *wlcompositor = NULL;
+struct wl_surface *wlsurface;
+struct wl_egl_window *wlegl_window;
+struct wl_region *wlregion;
+struct wl_shell *wlshell;
+struct wl_shell_surface *wlshell_surface;
+
+static void global_registry_handler(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version)
+{
+ printf("Got a registry event for %s id %d\n", interface, id);
+ if (strcmp(interface, "wl_compositor") == 0) {
+ wlcompositor = wl_registry_bind(registry,
+ id,
+ &wl_compositor_interface,
+ 1);
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ wlshell = wl_registry_bind(registry, id,
+ &wl_shell_interface, 1);
+ }
+}
+
+static void global_registry_remover(void *data, struct wl_registry *registry, uint32_t id)
+{
+ printf("Got a registry losing event for %d\n", id);
+}
+
+static const struct wl_registry_listener registry_listener = {
+ global_registry_handler,
+ global_registry_remover
+};
+
+static void get_server_references(void)
+{
+ wldisplay = wl_display_connect(NULL);
+ if (wldisplay == NULL) {
+ fprintf(stderr, "Can't connect to display\n");
+ exit(1);
+ }
+ printf("connected to display\n");
+
+ struct wl_registry *registry = wl_display_get_registry(wldisplay);
+ wl_registry_add_listener(registry, ®istry_listener, NULL);
+
+ wl_display_dispatch(wldisplay);
+ wl_display_roundtrip(wldisplay);
+
+ if (wlcompositor == NULL || wlshell == NULL) {
+ fprintf(stderr, "Can't find compositor or shell\n");
+ exit(1);
+ } else {
+ fprintf(stderr, "Found compositor and shell\n");
+ }
+}
+
+static void create_opaque_region()
+{
+ wlregion = wl_compositor_create_region(wlcompositor);
+ wl_region_add(wlregion, 0, 0,
+ 1024,
+ 1024);
+ wl_surface_set_opaque_region(wlsurface, wlregion);
+}
+
int main(int argc, char** argv)
{
struct CameraControlListener listener;
@@ -356,6 +425,22 @@
FocusRegion fr = { top: -200, left: -200, bottom: 200, right: 200, weight: 300};
android_camera_set_focus_region(cc, &fr);
+ /* Wayland Setup */
+ get_server_references();
+
+ wlsurface = wl_compositor_create_surface(wlcompositor);
+ if (wlsurface == NULL) {
+ fprintf(stderr, "Can't create surface\n");
+ exit(1);
+ } else {
+ fprintf(stderr, "Created surface\n");
+ }
+
+ wlshell_surface = wl_shell_get_shell_surface(wlshell, wlsurface);
+ wl_shell_surface_set_toplevel(wlshell_surface);
+
+ create_opaque_region();
+
/* EGL Setup */
EGLConfig ecfg;
EGLBoolean rv;
@@ -372,7 +457,7 @@
EGL_NONE
};
- EGLDisplay disp = eglGetDisplay(NULL);
+ EGLDisplay disp = eglGetDisplay((EGLNativeDisplayType)wldisplay);
assert(eglGetError() == EGL_SUCCESS);
assert(disp != EGL_NO_DISPLAY);
@@ -384,8 +469,16 @@
assert(eglGetError() == EGL_SUCCESS);
assert(rv == EGL_TRUE);
+ wlegl_window = wl_egl_window_create(wlsurface, 1024, 1024);
+ if (wlegl_window == EGL_NO_SURFACE) {
+ fprintf(stderr, "Can't create egl window\n");
+ exit(1);
+ } else {
+ fprintf(stderr, "Created egl window\n");
+ }
+
EGLSurface surface = eglCreateWindowSurface((EGLDisplay) disp, ecfg,
- (EGLNativeWindowType) NULL, NULL);
+ (EGLNativeWindowType) wlegl_window, NULL);
assert(eglGetError() == EGL_SUCCESS);
assert(surface != EGL_NO_SURFACE);
@@ -473,5 +566,9 @@
glDisableVertexAttribArray(gaTexHandle);
eglSwapBuffers((EGLDisplay) disp, surface);
+
+ wl_display_dispatch(wldisplay);
}
+
+ wl_display_disconnect(wldisplay);
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_gps.c
^
|
@@ -277,11 +277,19 @@
{
case GPS_REQUEST_AGPS_DATA_CONN:
fprintf(stdout, "*** data_conn_open\n");
- AGps->data_conn_open(apn);
+#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR < 2
+ AGps->data_conn_open(AGPS_TYPE_SUPL, apn, AGPS_APN_BEARER_IPV4);
+#else
+ AGps->data_conn_open(apn);
+#endif
break;
case GPS_RELEASE_AGPS_DATA_CONN:
fprintf(stdout, "*** data_conn_closed\n");
+#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR < 2
+ AGps->data_conn_closed(AGPS_TYPE_SUPL);
+#else
AGps->data_conn_closed();
+#endif
break;
case GPS_AGPS_DATA_CONNECTED:
fprintf(stdout, "*** data_conn_established\n");
@@ -395,7 +403,7 @@
fprintf(stdout, "*** cleanup\n");
if(AGps)
{
-#if ! defined(HAS_ANDROID_4_2_0) && ! defined(HAS_ANDROID_5_0_0)
+#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR < 2
AGps->data_conn_closed(AGPS_TYPE_SUPL);
#else
AGps->data_conn_closed();
@@ -603,7 +611,11 @@
}
if (AGps)
- AGps->data_conn_closed(AGPS_TYPE_SUPL);
+#if ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR < 2
+ AGps->data_conn_closed(AGPS_TYPE_SUPL);
+#else
+ AGps->data_conn_closed();
+#endif
fprintf(stdout, "*** stop tracking\n");
Gps->stop();
fprintf(stdout, "*** cleaning up\n");
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_hwc2.cpp
^
|
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2018 TheKit <nekit1000@gmail.com>
+ * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#if HAS_HWCOMPOSER2_HEADERS
+
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+#include <mutex>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <cutils/log.h>
+#include <sync/sync.h>
+
+#include <hwcomposer_window.h>
+
+#include <hybris/hwc2/hwc2_compatibility_layer.h>
+#include "logging.h"
+
+const char vertex_src [] =
+" \
+ attribute vec4 position; \
+ varying mediump vec2 pos; \
+ uniform vec4 offset; \
+ \
+ void main() \
+ { \
+ gl_Position = position + offset; \
+ pos = position.xy; \
+ } \
+";
+
+
+const char fragment_src [] =
+" \
+ varying mediump vec2 pos; \
+ uniform mediump float phase; \
+ \
+ void main() \
+ { \
+ gl_FragColor = vec4( 1., 0.9, 0.7, 1.0 ) * \
+ cos( 30.*sqrt(pos.x*pos.x + 1.5*pos.y*pos.y) \
+ + atan(pos.y,pos.x) - phase ); \
+ } \
+";
+
+GLuint load_shader(const char *shader_source, GLenum type)
+{
+ GLuint shader = glCreateShader(type);
+
+ glShaderSource(shader, 1, &shader_source, NULL);
+ glCompileShader(shader);
+
+ return shader;
+}
+
+
+GLfloat norm_x = 0.0;
+GLfloat norm_y = 0.0;
+GLfloat offset_x = 0.0;
+GLfloat offset_y = 0.0;
+GLfloat p1_pos_x = 0.0;
+GLfloat p1_pos_y = 0.0;
+
+GLint phase_loc;
+GLint offset_loc;
+GLint position_loc;
+
+const float vertexArray[] = {
+ 0.0, 1.0, 0.0,
+ -1., 0.0, 0.0,
+ 0.0, -1.0, 0.0,
+ 1., 0.0, 0.0,
+ 0.0, 1., 0.0
+};
+
+hwc2_compat_device_t* hwcDevice;
+
+class HWComposer : public HWComposerNativeWindow
+{
+ private:
+ hwc2_compat_layer_t *layer;
+ hwc2_compat_display_t *hwcDisplay;
+ int lastPresentFence = -1;
+ protected:
+ void present(HWComposerNativeWindowBuffer *buffer);
+
+ public:
+
+ HWComposer(unsigned int width, unsigned int height, unsigned int format,
+ hwc2_compat_display_t *display, hwc2_compat_layer_t *layer);
+ void set();
+};
+
+HWComposer::HWComposer(unsigned int width, unsigned int height,
+ unsigned int format, hwc2_compat_display_t* display,
+ hwc2_compat_layer_t *layer) :
+ HWComposerNativeWindow(width, height, format)
+{
+ this->layer = layer;
+ this->hwcDisplay = display;
+}
+
+void HWComposer::present(HWComposerNativeWindowBuffer *buffer)
+{
+ uint32_t numTypes = 0;
+ uint32_t numRequests = 0;
+ hwc2_display_t displayId = 0;
+
+ hwc2_error_t error = hwc2_compat_display_validate(hwcDisplay, &numTypes,
+ &numRequests);
+
+ if (error != HWC2_ERROR_NONE && error != HWC2_ERROR_HAS_CHANGES) {
+ HYBRIS_ERROR("prepare: validate failed for display %lu: %s (%d)", displayId,
+ to_string(static_cast<HWC2::Error>(error)).c_str(), error);
+ return;
+ }
+
+ if (numTypes || numRequests) {
+ HYBRIS_ERROR("prepare: validate required changes for display %lu: %s (%d)",
+ displayId, to_string(static_cast<HWC2::Error>(error)).c_str(),
+ error);
+ return;
+ }
+
+ error = hwc2_compat_display_accept_changes(hwcDisplay);
+ if (error != HWC2_ERROR_NONE) {
+ HYBRIS_ERROR("prepare: acceptChanges failed: %s",
+ to_string(static_cast<HWC2::Error>(error)).c_str());
+ return;
+ }
+
+ hwc2_compat_display_set_client_target(hwcDisplay, /* slot */0, buffer,
+ getFenceBufferFd(buffer),
+ HAL_DATASPACE_UNKNOWN);
+
+ int presentFence;
+ hwc2_compat_display_present(hwcDisplay, &presentFence);
+
+ if (error != HWC2_ERROR_NONE) {
+ HYBRIS_ERROR("presentAndGetReleaseFences: failed for display %lu: %s (%d)",
+ displayId,
+ to_string(static_cast<HWC2::Error>(error)).c_str(), error);
+ return;
+ }
+
+ hwc2_compat_out_fences_t* fences;
+ error = hwc2_compat_display_get_release_fences(
+ hwcDisplay, &fences);
+
+ if (error != HWC2_ERROR_NONE) {
+ HYBRIS_ERROR("presentAndGetReleaseFences: Failed to get release fences "
+ "for display %lu: %s (%d)",
+ displayId, to_string(static_cast<HWC2::Error>(error)).c_str(),
+ error);
+ return;
+ }
+
+ int fenceFd = hwc2_compat_out_fences_get_fence(fences, layer);
+ if (fenceFd != -1)
+ setFenceBufferFd(buffer, fenceFd);
+
+ hwc2_compat_out_fences_destroy(fences);
+
+ if (lastPresentFence != -1) {
+ sync_wait(lastPresentFence, -1);
+ close(lastPresentFence);
+ }
+ lastPresentFence = presentFence;
+}
+
+void onVsyncReceived(HWC2EventListener* listener, int32_t sequenceId,
+ hwc2_display_t display, int64_t timestamp)
+{
+}
+
+void onHotplugReceived(HWC2EventListener* listener, int32_t sequenceId,
+ hwc2_display_t display, bool connected,
+ bool primaryDisplay)
+{
+ HYBRIS_INFO("onHotplugReceived(%d, %" PRIu64 ", %s, %s)",
+ sequenceId, display,
+ connected ?
+ "connected" : "disconnected",
+ primaryDisplay ? "primary" : "external");
+
+ hwc2_compat_device_on_hotplug(hwcDevice, display, connected);
+}
+
+void onRefreshReceived(HWC2EventListener* listener,
+ int32_t sequenceId, hwc2_display_t display)
+{
+}
+
+HWC2EventListener eventListener = {
+ &onVsyncReceived,
+ &onHotplugReceived,
+ &onRefreshReceived
+};
+
+int main()
+{
+ EGLDisplay display;
+ EGLConfig ecfg;
+ EGLint num_config;
+ EGLint attr[] = { // some attributes to set up our egl-interface
+ EGL_BUFFER_SIZE, 32,
+ EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+ EGLSurface surface;
+ EGLint ctxattr[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+ EGLContext context;
+
+ EGLBoolean rv;
+
+ int err;
+ int composerSequenceId = 0;
+
+ hwcDevice = hwc2_compat_device_new(false);
+ assert(hwcDevice);
+
+ hwc2_compat_device_register_callback(hwcDevice, &eventListener,
+ composerSequenceId);
+
+ hwc2_compat_display_t* hwcDisplay;
+ for (int i = 0; i < 5 * 1000; ++i) {
+ /* Wait at most 5s for hotplug events */
+ if ((hwcDisplay = hwc2_compat_device_get_display_by_id(hwcDevice, 0)))
+ break;
+ usleep(1000);
+ }
+ assert(hwcDisplay);
+
+ hwc2_compat_display_set_power_mode(hwcDisplay, HWC2_POWER_MODE_ON);
+
+ HWC2DisplayConfig* config = hwc2_compat_display_get_active_config(hwcDisplay);
+
+ printf("width: %i height: %i\n", config->width, config->height);
+
+ hwc2_compat_layer_t* layer = hwc2_compat_display_create_layer(hwcDisplay);
+
+ hwc2_compat_layer_set_composition_type(layer, HWC2_COMPOSITION_CLIENT);
+ hwc2_compat_layer_set_blend_mode(layer, HWC2_BLEND_MODE_NONE);
+ hwc2_compat_layer_set_source_crop(layer, 0.0f, 0.0f, config->width,
+ config->height);
+ hwc2_compat_layer_set_display_frame(layer, 0, 0, config->width,
+ config->height);
+ hwc2_compat_layer_set_visible_region(layer, 0, 0, config->width,
+ config->height);
+
+ HWComposer *win = new HWComposer(config->width, config->height,
+ HAL_PIXEL_FORMAT_RGBA_8888, hwcDisplay,
+ layer);
+ printf("created native window\n");
+ /* Not needed with hybris window platform
+ * hybris_gralloc_initialize(0); */
+
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(display != EGL_NO_DISPLAY);
+
+ rv = eglInitialize(display, 0, 0);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(rv == EGL_TRUE);
+
+ eglChooseConfig((EGLDisplay) display, attr, &ecfg, 1, &num_config);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(rv == EGL_TRUE);
+
+ surface = eglCreateWindowSurface((EGLDisplay) display, ecfg,
+ (EGLNativeWindowType) static_cast<ANativeWindow *> (win), NULL);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(surface != EGL_NO_SURFACE);
+
+ context = eglCreateContext((EGLDisplay) display, ecfg, EGL_NO_CONTEXT,
+ ctxattr);
+ assert(eglGetError() == EGL_SUCCESS);
+ assert(context != EGL_NO_CONTEXT);
+
+ assert(eglMakeCurrent((EGLDisplay) display, surface, surface,
+ context) == EGL_TRUE);
+
+ const char *version = (const char *)glGetString(GL_VERSION);
+ assert(version);
+ printf("%s\n",version);
+
+ GLuint vertexShader = load_shader (vertex_src, GL_VERTEX_SHADER);
+ GLuint fragmentShader = load_shader(fragment_src, GL_FRAGMENT_SHADER);
+
+ GLuint shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, vertexShader);
+ glAttachShader(shaderProgram, fragmentShader);
+
+ glLinkProgram(shaderProgram);
+ glUseProgram(shaderProgram);
+
+ position_loc = glGetAttribLocation(shaderProgram, "position");
+ phase_loc = glGetUniformLocation(shaderProgram, "phase");
+ offset_loc = glGetUniformLocation(shaderProgram, "offset");
+
+ if (position_loc < 0 || phase_loc < 0 || offset_loc < 0) {
+ return 1;
+ }
+
+ glClearColor (1., 1., 1., 1.); // background color
+ float phase = 0;
+
+ for (int i=0; i<60*60; ++i) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUniform1f (phase_loc, phase);
+ phase = fmodf (phase + 0.5f, 2.f * 3.141f);
+
+ glUniform4f(offset_loc, offset_x, offset_y, 0.0, 0.0);
+
+ glVertexAttribPointer(position_loc, 3, GL_FLOAT,
+ GL_FALSE, 0, vertexArray);
+ glEnableVertexAttribArray (position_loc);
+ glDrawArrays (GL_TRIANGLE_STRIP, 0, 5);
+
+ eglSwapBuffers ((EGLDisplay) display, surface);
+ }
+
+ printf("stop\n");
+
+ return 0;
+}
+
+#else
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("test_hwc2 is not supported in this build\n");
+ return 0;
+}
+#endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_hwcomposer.cpp
^
|
@@ -16,6 +16,9 @@
*/
#include <android-config.h>
+
+#if ((ANDROID_VERSION_MAJOR >= 4 && ANDROID_VERSION_MINOR >= 2) || ANDROID_VERSION_MAJOR >= 5)
+
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <assert.h>
@@ -371,4 +374,14 @@
#endif
}
+#else
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("test_hwcomposer is not supported in this build\n");
+ return 0;
+}
+#endif
+
// vim:ts=4:sw=4:noexpandtab
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_nfc.c
^
|
@@ -17,6 +17,9 @@
*/
#include <android-config.h>
+
+#if HAS_LIBNFC_NXP_HEADERS
+
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
@@ -371,3 +374,15 @@
return 0;
}
+
+#else
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("test_nfc is not supported in this build\n");
+ return 0;
+}
+
+#endif
+
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_sensors.c
^
|
@@ -48,17 +48,30 @@
}
}
+void float_to_char(float f,char * buffer, int maxChars){
+ int beforeDot = (int)f;
+ int afterDot = (int)((f-beforeDot)*1e6); /* rounding is not perfect, but that'll do */
+ snprintf(buffer, maxChars, "%d.%d", beforeDot, afterDot);
+}
+
static void print_sensor_info(int i, struct sensor_t const *s)
{
+ char numStr[32];
+
printf("=== Sensor %d ==\n", i);
printf("Name: %s\n", s->name);
printf("Vendor: %s\n", s->vendor);
printf("Version: 0x%x\n", s->version);
printf("Handle: 0x%x\n", s->handle);
printf("Type: %d\n", s->type);
- printf("maxRange: %.f\n", s->maxRange);
- printf("resolution: %.f\n", s->resolution);
- printf("power: %.f mA\n", s->power);
+ // once the hw module is loaded, printf with %f will crash, so use integers
+ float_to_char(s->maxRange, numStr, 30);
+ printf("maxRange: %s\n", numStr);
+ float_to_char(s->resolution, numStr, 30);
+ printf("resolution: %s\n", numStr);
+ float_to_char(s->power, numStr, 30);
+ printf("power: %s mA\n", numStr);
+
printf("minDelay: %d\n", s->minDelay);
//printf("fifoReservedEventCount: %d\n", s->fifoReservedEventCount);
//printf("fifoMaxEventCount: %d\n", s->fifoMaxEventCount);
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_vibrator.c
^
|
@@ -16,6 +16,8 @@
*
*/
+#if HAS_VIBRATOR_HEADER
+
#include <android-config.h>
#include <assert.h>
#include <stdio.h>
@@ -54,4 +56,14 @@
return 0;
}
+#else
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("test_vibrator is not supported in this build");
+ return 0;
+}
+#endif
+
// vim:ts=4:sw=4:noexpandtab
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/tests/test_wifi.c
^
|
@@ -19,7 +19,9 @@
#include <string.h>
#include <android-config.h>
-#include <hardware_legacy/wifi.h>
+
+int wifi_load_driver();
+int wifi_unload_driver();
#define COMMAND_LOAD_WIFI "1"
#define COMMAND_UNLOAD_WIFI "0"
@@ -49,7 +51,6 @@
}
fprintf(stdout, "WiFi driver load state: %d\n", is_wifi_driver_loaded());
-
return 0;
}
|
[-]
[+]
|
Changed |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/hybris/wifi/wifi.c
^
|
@@ -20,7 +20,6 @@
#include <stddef.h>
#include <hybris/common/binding.h>
-#include <hardware_legacy/wifi.h>
#define COMPAT_LIBRARY_PATH "libhardware_legacy.so"
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/README
^
|
@@ -0,0 +1,18 @@
+libnfc wrapper generator scripts for libhybris
+==============================================
+
+These scripts generate libhybris wrapper libraries for Android libnfc.
+There are actually two different libnfc implementations in Android:
+
+ - libnfc-nxp
+ - libnfc-nci
+
+These scripts currently generate wrappers for libnfc-nxp, but could be
+adapted to generate wrappers for libnfc-nci as well.
+
+Usage:
+
+ git submodule init
+ git submodule update
+ sh -x generate.sh
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/README.android-src
^
|
@@ -0,0 +1,19 @@
+Clone to folder:
+ android_platform_frameworks_native
+URL:
+ https://android.googlesource.com/platform/frameworks/native
+
+Clone to folder:
+ android_platform_hardware_libhardware
+URL:
+ https://android.googlesource.com/platform/hardware/libhardware/
+
+Clone to folder:
+ android_platform_system_core
+URL:
+ https://android.googlesource.com/platform/system/core
+
+Clone to folder:
+ android_platform_external_libnfc-nxp
+URL:
+ https://android.googlesource.com/platform/external/libnfc-nxp
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/generate.sh
^
|
@@ -0,0 +1,30 @@
+#!/bin/sh -e
+# Generate C prototype definitions for Android libnfc
+# Copyright (C) 2013 Jolla Ltd.
+# Contact: Thomas Perl <thomas.perl@jollamobile.com>
+
+mkdir -p output
+
+cproto -x \
+ android_platform_external_libnfc-nxp/*/*.c \
+ -I android_platform_external_libnfc-nxp/inc \
+ -I android_platform_external_libnfc-nxp/src \
+ -I android_platform_external_libnfc-nxp/Linux_x86 \
+ -I android_platform_hardware_libhardware/include \
+ -I android_platform_system_core/include \
+ -I android_platform_frameworks_native/include \
+ -I . -DNXP_MESSAGING \
+ > output/libnfc_prototypes.h
+
+python generate_wrappers.py \
+ output/libnfc_prototypes.h \
+ symbols/libnfc.so.txt \
+ /system/lib/libnfc.so \
+ > output/libnfc-nxp.c
+
+python generate_wrappers.py \
+ output/libnfc_prototypes.h \
+ symbols/libnfc_ndef.so.txt \
+ /system/lib/libnfc_ndef.so \
+ > output/libnfc_ndef-nxp.c
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/generate_wrappers.py
^
|
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+# gnerate_wrappers.py: Parse header and output libhybris binding code
+# Adapted for libhybris from apkenv-wrapper-generator
+#
+# apkenv-wrapper-generator version:
+# Copyright (C) 2012 Thomas Perl <m@thp.io>; 2012-10-19
+#
+# libhybris version:
+# Copyright (C) 2013 Jolla Ltd.
+# Contact: Thomas Perl <thomas.perl@jollamobile.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+import re
+import os
+import sys
+
+# Some special cases to to avoid having to parse the full C grammar
+FIXED_MAPPINGS = {
+}
+
+# Never generate wrappers for these functions
+BLACKLISTED_FUNCS = [
+]
+
+def clean_arg(arg):
+ arg = arg.strip()
+ arg = arg.replace('__const', 'const')
+
+ while '[' in arg:
+ # int x[] -> int *x
+ arg = re.sub(r'(.*?)([A-Za-z_]+)(\[[^\]]*\])(.*)$', r'\1*\2\4', arg)
+
+ return arg.strip()
+
+class Argument:
+ def __init__(self, type_, name):
+ self.type_ = type_
+ self.name = name
+
+class Function:
+ def __init__(self, retval, name, args):
+ self.retval = retval
+ self.name = name
+ self.raw_args = args
+ self.parsing_error = None
+ self.args = list(self._parse_args(args))
+
+ def _parse_args(self, args):
+ for arg in map(clean_arg, args.split(',')):
+ arg = clean_arg(arg)
+ xarg = re.match(r'^(.*?)([A-Za-z0-9_]+)$', arg)
+ if not xarg:
+ # Unknown argument
+ if arg in FIXED_MAPPINGS:
+ yield Argument(FIXED_MAPPINGS[arg], '__undefined__')
+ continue
+ self.parsing_error = 'Could not parse: ' + repr(arg)
+ print self.parsing_error
+ continue
+ type_, name = xarg.groups()
+ if type_ == '':
+ type_ = name
+ name = '__undefined__'
+ yield Argument(type_, name)
+
+def parse_header(filename):
+ """Parse header file written by cproto"""
+ for line in open(filename):
+ if line.startswith('/*'):
+ continue
+ retval, funcname, args = re.match(r'^(.+ [*]?)([A-Za-z0-9_]+)\((.*)\);\s*$', line).groups()
+ retval, funcname, args = [x.strip() for x in (retval, funcname, args)]
+ if funcname not in BLACKLISTED_FUNCS:
+ yield (funcname, Function(retval, funcname, args))
+
+def parse_symbols(filename):
+ """Parse 'objdump -T'-style symbol list"""
+ for line in open(filename):
+ line = line.strip()
+ if not line:
+ continue
+
+ items = line.split()
+ if len(items) != 6:
+ continue
+
+ if 'DF' in items and '.text' in items:
+ # Print exported symbol name from text segment in library
+ yield items[-1]
+
+
+
+if len(sys.argv) != 4:
+ print >>sys.stderr, """
+ Usage: %s headerfile.h objdump-Tfile.so.txt /system/lib/something.so
+ """ % (sys.argv[0],)
+ sys.exit(1)
+
+
+headerfile = sys.argv[1]
+symbolsfile = sys.argv[2]
+libraryfile = sys.argv[3]
+
+libname = os.path.basename(libraryfile).replace('.', '_')
+
+available_functions = dict(parse_header(headerfile))
+
+print """
+#include <hybris/internal/binding.h>
+
+HYBRIS_LIBRARY_INITIALIZE(%s, "%s");
+""" % (libname, libraryfile)
+
+for symbol in parse_symbols(symbolsfile):
+ if symbol not in available_functions:
+ print '/* XXX No prototype for exported symbol: %s */' % symbol
+ continue
+
+ function = available_functions[symbol]
+ args = [a.type_.strip() for a in function.args if a.type_.strip() not in ('', 'void')]
+ if function.retval == 'void':
+ print 'HYBRIS_IMPLEMENT_VOID_FUNCTION%d(%s, %s);' % (len(args), libname, ', '.join([function.name] + args))
+ else:
+ print 'HYBRIS_IMPLEMENT_FUNCTION%d(%s, %s, %s);' % (len(args), libname, function.retval, ', '.join([function.name] + args))
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/linux/README
^
|
@@ -0,0 +1,5 @@
+This is just a dummy include directory, so the file
+
+android_platform_external_libnfc-nxp/Linux_x86/phDal4Nfc_i2c.c
+
+can be properly parsed by cproto.
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/linux/pn544.h
^
|
@@ -0,0 +1 @@
+/* Dummy header */
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/symbols/README
^
|
@@ -0,0 +1,3 @@
+These symbols have been obtained via:
+
+ objdump -T <filename>
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/symbols/libnfc.so.txt
^
|
@@ -0,0 +1,603 @@
+
+libnfc.so: file format elf32-little
+
+DYNAMIC SYMBOL TABLE:
+0000790c g DF .text 00000020 phLibNfc_Mgt_ConfigureDriver
+0003d120 g DF .text 00000394 phDal4Nfc_Config
+00000000 DF *UND* 00000000 __aeabi_unwind_cpp_pr0
+0000792c g DF .text 00000020 phLibNfc_Mgt_UnConfigureDriver
+0003d018 g DF .text 00000108 phDal4Nfc_ConfigRelease
+0000794c g DF .text 00000020 phLibNfc_HW_Reset
+0003d630 g DF .text 00000020 phDal4Nfc_Reset
+00000000 DF *UND* 00000000 __aeabi_unwind_cpp_pr1
+0000796c g DF .text 00000004 phLibNfc_Download_Mode
+0003d650 g DF .text 0000002c phDal4Nfc_Download
+00007970 g DF .text 00000004 phLibNfc_Load_Firmware_Image
+0000f3ec g DF .text 000000fc dlopen_firmware
+00007974 g DF .text 00000024 phLibNfc_Mgt_Recovery
+00000000 DF *UND* 00000000 usleep
+00007998 g DF .text 00000018 phLibNfc_SetIsoXchgTimeout
+0004102e g DO .data 00000001 nxp_nfc_isoxchg_timeout
+000079b0 g DF .text 00000014 phLibNfc_GetIsoXchgTimeout
+000079c4 g DF .text 00000018 phLibNfc_SetHciTimeout
+00041028 g DO .data 00000004 nxp_nfc_hci_response_timeout
+000079dc g DF .text 00000014 phLibNfc_GetHciTimeout
+000079f0 g DF .text 00000018 phLibNfc_SetFelicaTimeout
+00041021 g DO .data 00000001 nxp_nfc_felica_timeout
+00007a08 g DF .text 00000014 phLibNfc_GetFelicaTimeout
+00007a1c g DF .text 00000018 phLibNfc_SetMifareRawTimeout
+0004102d g DO .data 00000001 nxp_nfc_mifareraw_timeout
+00007a34 g DF .text 00000014 phLibNfc_GetMifareRawTimeout
+00007a48 g DF .text 000000f4 phLibNfc_Mgt_DeInitialize
+0000fa30 g DF .text 000000ac phHal4Nfc_Close
+0000fadc g DF .text 00000130 phHal4Nfc_Hal4Reset
+0003c0ec g DF .text 0000000c phOsalNfc_FreeMemory
+0000c370 g DF .text 000000cc phLibNfc_Ndef_DeInit
+00007b3c g DF .text 00000030 phLibNfc_Pending_Shutdown
+00007b6c g DF .text 000003c8 phLibNfc_Mgt_Reset
+00000000 DF *UND* 00000000 memset
+00041058 g DO .bss 00000004 pNdefRecord
+00041498 g DO .bss 00000014 NdefInfo
+00007f34 g DF .text 000000ec phLibNfc_UpdateNextState
+00008020 g DF .text 000000fc phLibNfc_Mgt_Initialize
+0003c0e8 g DF .text 00000004 phOsalNfc_GetMemory
+0000f4e8 g DF .text 00000278 phHal4Nfc_Open
+0000c1f8 g DF .text 00000178 phLibNfc_Ndef_Init
+0000811c g DF .text 00000064 phLibNfc_UpdateCurState
+0000e4b8 g DF .text 000000c4 phHal4Nfc_RegisterNotification
+00041480 g DO .bss 00000018 sSecuredElementInfo
+0003c0fc g DF .text 00000014 phOsalNfc_RaiseException
+00008424 g DF .text 00000180 phLibNfc_Mgt_GetstackCapabilities
+0000fc0c g DF .text 000000b8 phHal4Nfc_GetDeviceCapabilities
+00000000 DF *UND* 00000000 memcpy
+00000000 DF *UND* 00000000 memcmp
+00000000 DF *UND* 00000000 __android_log_print
+000410a0 g DO .bss 00000004 nxp_nfc_full_version
+000085a4 g DF .text 000001c4 phLibNfc_Mgt_ConfigureTestMode
+00041040 g DO .bss 00000004 gpphLibContext
+00008814 g DF .text 000000b8 phLibNfc_config_discovery_cb
+000088cc g DF .text 000000e8 phLibNfc_Mgt_ConfigureDiscovery
+0000db9c g DF .text 000001a0 phHal4Nfc_ConfigureDiscovery
+000089b4 g DF .text 00000130 phLibNfc_RemoteDev_CheckPresence
+0001130c g DF .text 000000cc phHal4Nfc_PresenceCheck
+00010bb8 g DF .text 0000059c phHal4Nfc_Transceive
+000109a8 g DF .text 00000210 phHal4Nfc_Connect
+0000ac0c g DF .text 00000140 phLibNfc_Reconnect_Mifare_Cb
+0000929c g DF .text 000000c0 phLibNfc_RemoteDev_NtfRegister
+0000935c g DF .text 00000078 phLibNfc_RemoteDev_NtfUnregister
+0000e57c g DF .text 000000c8 phHal4Nfc_UnregisterNotification
+000093d4 g DF .text 0000015c phLibNfc_RemoteDev_ReConnect
+00009530 g DF .text 00000164 phLibNfc_RemoteDev_Connect
+00009694 g DF .text 0000012c phLibNfc_RemoteDev_Disconnect
+0001120c g DF .text 00000100 phHal4Nfc_Disconnect
+000097c0 g DF .text 00000264 phLibNfc_RemoteDev_Transceive
+00009a24 g DF .text 00000128 phLibNfc_Mgt_SetP2P_ConfigParams
+0000da58 g DF .text 00000144 phHal4Nfc_ConfigParameters
+00000000 DF *UND* 00000000 __stack_chk_fail
+00000000 DO *UND* 00000000 __stack_chk_guard
+0002541c g DF .text 000000bc phFriNfc_LlcpTransport_CloseAll
+00009d44 g DF .text 0000018c phLibNfc_Mgt_SetLlcp_ConfigParams
+00023708 g DF .text 00000154 phFriNfc_Llcp_EncodeLinkParams
+00023be8 g DF .text 000000f0 phFriNfc_Llcp_Reset
+00024a6c g DF .text 00000188 phFriNfc_LlcpTransport_Reset
+00009ed0 g DF .text 0000010c phLibNfc_Llcp_CheckLlcp
+00023cd8 g DF .text 00000060 phFriNfc_Llcp_ChkLlcp
+00009fdc g DF .text 00000058 phLibNfc_Llcp_Activate
+00023d38 g DF .text 0000002c phFriNfc_Llcp_Activate
+0000a034 g DF .text 00000058 phLibNfc_Llcp_Deactivate
+00023d64 g DF .text 00000084 phFriNfc_Llcp_Deactivate
+0000a08c g DF .text 0000004c phLibNfc_Llcp_GetLocalInfo
+00023de8 g DF .text 0000003c phFriNfc_Llcp_GetLocalInfo
+0000a0d8 g DF .text 00000064 phLibNfc_Llcp_GetRemoteInfo
+00023e24 g DF .text 0000003c phFriNfc_Llcp_GetRemoteInfo
+0000a13c g DF .text 000000d8 phLibNfc_Llcp_DiscoverServices
+000250a4 g DF .text 0000004c phFriNfc_LlcpTransport_DiscoverServices
+0000a214 g DF .text 0000008c phLibNfc_Llcp_Socket
+000250f0 g DF .text 00000300 phFriNfc_LlcpTransport_Socket
+0000a2a0 g DF .text 00000034 phLibNfc_Llcp_Close
+000253f0 g DF .text 0000002c phFriNfc_LlcpTransport_Close
+0000a2d4 g DF .text 00000040 phLibNfc_Llcp_SocketGetLocalOptions
+00025034 g DF .text 00000038 phFriNfc_LlcpTransport_SocketGetLocalOptions
+0000a314 g DF .text 00000060 phLibNfc_Llcp_SocketGetRemoteOptions
+0002506c g DF .text 00000038 phFriNfc_LlcpTransport_SocketGetRemoteOptions
+0000a374 g DF .text 00000044 phLibNfc_Llcp_Bind
+000254d8 g DF .text 00000218 phFriNfc_LlcpTransport_Bind
+0000a3b8 g DF .text 00000048 phLibNfc_Llcp_Listen
+000256f0 g DF .text 00000054 phFriNfc_LlcpTransport_Listen
+0000a400 g DF .text 0000007c phLibNfc_Llcp_Accept
+00025744 g DF .text 000000d0 phFriNfc_LlcpTransport_Accept
+0000a47c g DF .text 00000068 phLibNfc_Llcp_Reject
+00025814 g DF .text 00000034 phFriNfc_LlcpTransport_Reject
+0000a4e4 g DF .text 0000006c phLibNfc_Llcp_Connect
+00025848 g DF .text 000000cc phFriNfc_LlcpTransport_Connect
+0000a550 g DF .text 00000070 phLibNfc_Llcp_ConnectByUri
+00025914 g DF .text 000000c0 phFriNfc_LlcpTransport_ConnectByUri
+0000a5c0 g DF .text 00000068 phLibNfc_Llcp_Disconnect
+000259d4 g DF .text 00000038 phFriNfc_LlcpTransport_Disconnect
+0000a628 g DF .text 00000070 phLibNfc_Llcp_Recv
+00025a84 g DF .text 00000060 phFriNfc_LlcpTransport_Recv
+0000a698 g DF .text 00000070 phLibNfc_Llcp_RecvFrom
+00025bbc g DF .text 00000064 phFriNfc_LlcpTransport_RecvFrom
+0000a708 g DF .text 00000070 phLibNfc_Llcp_Send
+00025a0c g DF .text 00000078 phFriNfc_LlcpTransport_Send
+0000a778 g DF .text 00000084 phLibNfc_Llcp_SendTo
+00025ae4 g DF .text 000000d8 phFriNfc_LlcpTransport_SendTo
+0000a930 g DF .text 000002dc phLibNfc_Mgt_IoCtl
+0000f760 g DF .text 000002d0 phHal4Nfc_Ioctl
+0000fe6c g DF .text 000000e8 phHal4Nfc_Switch_Swp_Mode
+00000000 DF *UND* 00000000 phFriNfc_NdefRecord_GetRecords
+00037da8 g DF .text 00000044 phFriNfc_NdefReg_DispatchPacket
+00037e14 g DF .text 00000564 phFriNfc_NdefReg_Process
+00037d04 g DF .text 000000a4 phFriNfc_NdefReg_RmCb
+00000000 DF *UND* 00000000 phFriNfc_NdefRecord_Parse
+000378b4 g DF .text 00000238 phFriNfc_NdefMap_GetContainerSize
+0003bf2c g DF .text 00000070 phOsalNfc_Timer_Stop
+0003c0a0 g DF .text 00000048 phOsalNfc_Timer_Delete
+0000bc40 g DF .text 0000030c phLibNfc_Ndef_Read
+00037338 g DF .text 00000040 phFriNfc_NdefMap_SetCompletionRoutine
+00037378 g DF .text 00000150 phFriNfc_NdefMap_RdNdef
+0000bf4c g DF .text 000002ac phLibNfc_Ndef_Write
+00037850 g DF .text 00000064 phFriNfc_NdefMap_EraseNdef
+000374c8 g DF .text 00000180 phFriNfc_NdefMap_WrNdef
+0000c43c g DF .text 000001c0 phLibNfc_Ndef_CheckNdef
+0003715c g DF .text 000001dc phFriNfc_NdefMap_Reset
+000376a0 g DF .text 000000f4 phFriNfc_NdefMap_ChkNdef
+0003be58 g DF .text 000000d4 phOsalNfc_Timer_Start
+0003bdac g DF .text 000000ac phOsalNfc_Timer_Create
+0000c5fc g DF .text 000001f4 phLibNfc_RemoteDev_FormatNdef
+0003b188 g DF .text 000000cc phFriNfc_NdefSmtCrd_Reset
+0003b254 g DF .text 00000044 phFriNfc_NdefSmtCrd_SetCR
+0003b2f8 g DF .text 000000f0 phFriNfc_NdefSmtCrd_Format
+0000c7f0 g DF .text 000002f0 phLibNfc_ConvertToReadOnlyNdef
+00037648 g DF .text 00000058 phFriNfc_NdefMap_ConvertToReadOnly
+0003b298 g DF .text 00000060 phFriNfc_NdefSmtCrd_ConvertToReadOnly
+0002ebec g DF .text 00000130 phFriNfc_MifareStdMap_ConvertToReadOnly
+0000cae0 g DF .text 00000268 phLibNfc_Ndef_SearchNdefContent
+00037c14 g DF .text 0000007c phFriNfc_NdefReg_Reset
+00037c90 g DF .text 00000074 phFriNfc_NdefReg_AddCb
+0000d0d0 g DF .text 0000008c phLibNfc_SE_NtfRegister
+0000d15c g DF .text 00000070 phLibNfc_SE_NtfUnregister
+0000d1cc g DF .text 00000100 phLibNfc_SE_GetSecureElementList
+0000d2cc g DF .text 00000320 phLibNfc_SE_SetMode
+0000fd0c g DF .text 00000160 phHal4Nfc_Switch_SMX_Mode
+0000d780 g DF .text 00000124 phLibNfc_RemoteDev_Receive
+000101b4 g DF .text 00000158 phHal4Nfc_Receive
+0000d8a4 g DF .text 000001b4 phLibNfc_RemoteDev_Send
+0000ffe8 g DF .text 000001cc phHal4Nfc_Send
+00014484 g DF .text 00000180 phHciNfc_Configure
+00014604 g DF .text 00000088 phHciNfc_Config_Discovery
+0001468c g DF .text 00000120 phHciNfc_Restart_Discovery
+0000dd3c g DF .text 000000b4 phHal4Nfc_ConfigureComplete
+000116f8 g DF .text 00000180 phHal4Nfc_DisconnectComplete
+0000ddf0 g DF .text 000006c8 phHal4Nfc_TargetDiscoveryComplete
+000148ec g DF .text 00000068 phHciNfc_Select_Next_Target
+000414b8 g DO .bss 00000004 gpphHal4Nfc_Hwref
+0000fcc4 g DF .text 00000048 phHal4Nfc_HandleEmulationEvent
+00011878 g DF .text 00000128 phHal4Nfc_TransceiveComplete
+0001030c g DF .text 0000024c phHal4Nfc_SendCompleteHandler
+000114e8 g DF .text 00000060 phHal4Nfc_ReactivationComplete
+000113d8 g DF .text 00000110 phHal4Nfc_PresenceChkComplete
+00011548 g DF .text 000001b0 phHal4Nfc_ConnectComplete
+00010558 g DF .text 000001ac phHal4Nfc_RecvCompleteHandler
+000143b0 g DF .text 000000d4 phHciNfc_Release
+00010830 g DF .text 0000013c phHal4Nfc_HandleP2PDeActivate
+00010704 g DF .text 0000012c phHal4Nfc_P2PActivateComplete
+00000000 DF *UND* 00000000 dlopen
+00000000 DF *UND* 00000000 dlsym
+000141e0 g DF .text 000001d0 phHciNfc_Initialise
+0003cf04 g DF .text 00000114 phDal4Nfc_Register
+00020850 g DF .text 0000011c phLlcNfc_Register
+00015008 g DF .text 00000080 phHciNfc_System_Get_Info
+00014edc g DF .text 000000b4 phHciNfc_System_Test
+00014f90 g DF .text 00000078 phHciNfc_System_Configure
+00014e60 g DF .text 0000007c phHciNfc_PRBS_Test
+000133bc g DF .text 00000378 phDnldNfc_Upgrade
+00013338 g DF .text 00000084 phDnldNfc_Run_Check
+00041080 g DO .bss 00000004 nxp_nfc_fw
+0001482c g DF .text 000000c0 phHciNfc_Switch_SmxMode
+000147ac g DF .text 00000080 phHciNfc_Switch_SwpMode
+00014cd4 g DF .text 000000d8 phHciNfc_Send_Data
+00011154 g DF .text 000000b8 phHal4Nfc_Disconnect_Execute
+0001096c g DF .text 0000003c phHal4Nfc_Felica_RePoll
+000414b4 g DO .bss 00000004 gpHal4Ctxt
+00014a14 g DF .text 00000104 phHciNfc_Reactivate
+0003c36c g DF .text 0000004c phOsalNfc_MemCompare
+00014954 g DF .text 000000c0 phHciNfc_Connect
+00014bf0 g DF .text 000000e4 phHciNfc_Exchange_Data
+00014b18 g DF .text 000000d8 phHciNfc_Disconnect
+00014dac g DF .text 000000b4 phHciNfc_Presence_Check
+0003cb70 g DF .text 00000044 phDal4Nfc_Unregister
+00017534 g DF .text 00000018 phHciNfc_Build_HCPFrame
+00017584 g DF .text 000001b0 phHciNfc_Send_HCP
+0001afa0 g DF .text 00000214 phHciNfc_Update_PipeInfo
+00013b10 g DF .text 00000058 phHciNfc_Admin_Release
+0001b3b0 g DF .text 00000050 phHciNfc_Close_Pipe
+00013b68 g DF .text 000000b8 phHciNfc_Send_Admin_Event
+00013c74 g DF .text 00000134 phHciNfc_Send_Admin_Cmd
+00013da8 g DF .text 00000438 phHciNfc_Admin_Initialise
+00017214 g DF .text 0000003c phHciNfc_Allocate_Resource
+0001acc0 g DF .text 0000028c phHciNfc_Create_All_Pipes
+0001b360 g DF .text 00000050 phHciNfc_Open_Pipe
+00017734 g DF .text 0000011c phHciNfc_Send_Generic_Cmd
+00017850 g DF .text 00000054 phHciNfc_Set_Param
+0001b1b4 g DF .text 000001ac phHciNfc_Update_Pipe
+0001e180 g DF .text 00000034 phHciNfc_FSM_Update
+0001e1f8 g DF .text 0000002c phHciNfc_FSM_Rollback
+000178a4 g DF .text 0000018c phHciNfc_Send_Complete
+00017a30 g DF .text 0000049c phHciNfc_Receive_Complete
+00018048 g DF .text 00000314 phHciNfc_Notify_Event
+0001e728 g DF .text 00000250 phHciNfc_Release_Sequence
+000174d4 g DF .text 00000030 phHciNfc_Release_Lower
+00017250 g DF .text 00000284 phHciNfc_Release_Resources
+0001a82c g DF .text 0000009c phHciNfc_NfcIP_SetATRInfo
+0001fd18 g DF .text 00000078 phHciNfc_SWP_Protection
+0001fe8c g DF .text 0000007c phHciNfc_SWP_Update_Sequence
+0001f02c g DF .text 00000094 phHciNfc_EmulationCfg_Sequence
+00016880 g DF .text 00000098 phHciNfc_Emulation_Cfg
+0001edcc g DF .text 00000260 phHciNfc_PollLoop_Sequence
+0001d170 g DF .text 00000130 phHciNfc_ReaderMgmt_Deselect
+0001fd90 g DF .text 000000fc phHciNfc_SWP_Configure_Mode
+0001f0c0 g DF .text 000001c4 phHciNfc_SmartMx_Mode_Sequence
+0001d93c g DF .text 000000c8 phHciNfc_ReaderMgmt_Activate_Next
+0001de60 g DF .text 000001b0 phHciNfc_ReaderMgmt_Select
+0001da04 g DF .text 0000015c phHciNfc_ReaderMgmt_Reactivate
+0001f530 g DF .text 00000110 phHciNfc_Disconnect_Sequence
+0001d6e0 g DF .text 0000025c phHciNfc_ReaderMgmt_Exchange_Data
+0001a278 g DF .text 0000010c phHciNfc_NfcIP_Send_Data
+0001db60 g DF .text 00000210 phHciNfc_ReaderMgmt_Presence_Check
+00015da8 g DF .text 000000b4 phHciNfc_DevMgmt_Test
+000156f4 g DF .text 0000009c phHciNfc_DevMgmt_Get_Info
+00015658 g DF .text 0000009c phHciNfc_DevMgmt_Configure
+00015088 g DF .text 0000005c phHciNfc_Get_Link_Status
+00019930 g DF .text 0000004c phHciNfc_LinkMgmt_Open
+0001754c g DF .text 00000038 phHciNfc_Append_HCPFrame
+000154f8 g DF .text 00000068 phHciNfc_DevMgmt_Init_Resources
+00015560 g DF .text 00000040 phHciNfc_DevMgmt_Get_PipeID
+000155a0 g DF .text 00000034 phHciNfc_DevMgmt_Get_Test_Result
+000155d4 g DF .text 00000024 phHciNfc_DevMgmt_Set_Test_Result
+000155f8 g DF .text 00000060 phHciNfc_DevMgmt_Update_PipeInfo
+00015790 g DF .text 00000494 phHciNfc_DevMgmt_Initialise
+00015c24 g DF .text 00000108 phHciNfc_DevMgmt_Release
+00015d2c g DF .text 0000007c phHciNfc_DevMgmt_Update_Sequence
+00016104 g DF .text 000000dc phHciNfc_Uicc_Connectivity
+000161e0 g DF .text 0000002c phHciNfc_Uicc_Get_PipeID
+0001620c g DF .text 0000005c phHciNfc_Uicc_Update_PipeInfo
+00016268 g DF .text 0000009c phHciNfc_EmuMgmt_Update_Seq
+00016304 g DF .text 0000008c phHciNfc_Uicc_Connect_Status
+0001fc9c g DF .text 00000048 phHciNfc_SWP_Get_Status
+00016390 g DF .text 00000394 phHciNfc_EmuMgmt_Initialise
+00020378 g DF .text 000000fc phHciNfc_WI_Configure_Mode
+0001a648 g DF .text 00000084 phHciNfc_NfcIP_SetMode
+0001fce4 g DF .text 00000034 phHciNfc_SWP_Get_Bitrate
+0001ab74 g DF .text 00000078 phHciNfc_NfcIP_SetMergeSak
+0001fc24 g DF .text 00000078 phHciNfc_SWP_Configure_Default
+000202b0 g DF .text 00000070 phHciNfc_WI_Configure_Default
+00020474 g DF .text 00000080 phHciNfc_WI_Configure_Notifications
+00016724 g DF .text 0000015c phHciNfc_EmuMgmt_Release
+0001ff08 g DF .text 00000098 phHciNfc_SWP_Config_Sequence
+0001cb14 g DF .text 000000d8 phHciNfc_ReaderMgmt_Update_Sequence
+00016d0c g DF .text 0000002c phHciNfc_Felica_Get_PipeID
+00016d38 g DF .text 0000006c phHciNfc_Felica_Init_Resources
+00016da4 g DF .text 00000054 phHciNfc_Felica_Update_PipeInfo
+00016df8 g DF .text 00000060 phHciNfc_Felica_Update_Info
+00016e58 g DF .text 00000120 phHciNfc_Felica_Info_Sequence
+00017ef0 g DF .text 0000007c phHciNfc_Tag_Notify
+00016f78 g DF .text 00000148 phHciNfc_Send_Felica_Command
+000170c0 g DF .text 00000088 phHciNfc_Felica_Request_Mode
+00017504 g DF .text 00000030 phHciNfc_Receive
+0001f640 g DF .text 000003a4 phHciNfc_Resume_Sequence
+0001e978 g DF .text 00000454 phHciNfc_Error_Sequence
+00017ecc g DF .text 00000024 phHciNfc_Notify
+0001e1b4 g DF .text 00000044 phHciNfc_FSM_Complete
+00017f6c g DF .text 00000088 phHciNfc_Target_Select_Notify
+00017ff4 g DF .text 00000054 phHciNfc_Release_Notify
+000185b4 g DF .text 0000006c phHciNfc_IDMgmt_Init_Resources
+00018620 g DF .text 0000002c phHciNfc_IDMgmt_Get_PipeID
+0001864c g DF .text 00000090 phHciNfc_IDMgmt_Update_Sequence
+000186dc g DF .text 00000058 phHciNfc_IDMgmt_Initialise
+00018734 g DF .text 00000164 phHciNfc_IDMgmt_Info_Sequence
+00018898 g DF .text 00000030 phHciNfc_IDMgmt_Release
+000188c8 g DF .text 0000004c phHciNfc_IDMgmt_Update_PipeInfo
+00018b94 g DF .text 00000064 phHciNfc_ISO15693_Init_Resources
+00018bf8 g DF .text 00000030 phHciNfc_ISO15693_Get_PipeID
+00018c28 g DF .text 00000068 phHciNfc_ISO15693_Update_PipeInfo
+00018c90 g DF .text 00000060 phHciNfc_ISO15693_Update_Info
+00018cf0 g DF .text 000000f8 phHciNfc_ISO15693_Info_Sequence
+00018de8 g DF .text 000000f4 phHciNfc_Send_ISO15693_Command
+00018edc g DF .text 0000007c phHciNfc_ISO15693_Set_AFI
+000192e8 g DF .text 0000002c phHciNfc_Jewel_Get_PipeID
+00019314 g DF .text 0000006c phHciNfc_Jewel_Init_Resources
+00019380 g DF .text 00000054 phHciNfc_Jewel_Update_PipeInfo
+000193d4 g DF .text 00000060 phHciNfc_Jewel_Update_Info
+00019434 g DF .text 000000f4 phHciNfc_Send_Jewel_Command
+00019528 g DF .text 000000f4 phHciNfc_Jewel_Info_Sequence
+0001961c g DF .text 00000084 phHciNfc_Jewel_GetRID
+0001979c g DF .text 00000194 phHciNfc_LinkMgmt_Initialise
+0001997c g DF .text 00000030 phHciNfc_LinkMgmt_Release
+00019fe8 g DF .text 0000006c phHciNfc_Initiator_Init_Resources
+0001a054 g DF .text 00000030 phHciNfc_Initiator_Get_PipeID
+0001a084 g DF .text 00000054 phHciNfc_Initiator_Update_PipeInfo
+0001a0d8 g DF .text 000000b4 phHciNfc_NfcIP_Presence_Check
+0001a18c g DF .text 00000068 phHciNfc_Target_Init_Resources
+0001a1f4 g DF .text 00000030 phHciNfc_Target_Get_PipeID
+0001a224 g DF .text 00000054 phHciNfc_Target_Update_PipeInfo
+0001a384 g DF .text 000002c4 phHciNfc_NfcIP_Info_Sequence
+0001a6cc g DF .text 0000007c phHciNfc_NfcIP_SetNAD
+0001a748 g DF .text 00000070 phHciNfc_NfcIP_SetDID
+0001a7b8 g DF .text 00000074 phHciNfc_NfcIP_SetOptions
+0001a8c8 g DF .text 00000070 phHciNfc_NfcIP_SetPSL1
+0001a938 g DF .text 00000070 phHciNfc_NfcIP_SetPSL2
+0001a9a8 g DF .text 0000005c phHciNfc_NfcIP_GetStatus
+0001aa04 g DF .text 0000005c phHciNfc_NfcIP_GetParam
+0001aa60 g DF .text 000000b0 phHciNfc_Initiator_Cont_Activate
+0001ab10 g DF .text 00000064 phHciNfc_NfcIP_GetATRInfo
+0001ac78 g DF .text 00000048 phHciNfc_Delete_Pipe
+0001fb60 g DF .text 00000068 phHciNfc_SWP_Init_Resources
+0001b5b8 g DF .text 00000070 phHciNfc_PollLoop_Init_Resources
+0001bd5c g DF .text 0000006c phHciNfc_ReaderA_Init_Resources
+0001c770 g DF .text 0000006c phHciNfc_ReaderB_Init_Resources
+000201c0 g DF .text 00000068 phHciNfc_WI_Init_Resources
+0001af4c g DF .text 00000054 phHciNfc_Delete_All_Pipes
+0001b8a8 g DF .text 0000005c phHciNfc_PollLoop_Update_PipeInfo
+00020254 g DF .text 0000005c phHciNfc_WI_Update_PipeInfo
+0001fbc8 g DF .text 0000005c phHciNfc_SWP_Update_PipeInfo
+0001c83c g DF .text 00000054 phHciNfc_ReaderB_Update_PipeInfo
+0001bdc8 g DF .text 0000005c phHciNfc_ReaderA_Update_PipeInfo
+0001cbec g DF .text 000002a4 phHciNfc_ReaderMgmt_Initialise
+0001b58c g DF .text 0000002c phHciNfc_PollLoop_Get_PipeID
+0001b628 g DF .text 00000048 phHciNfc_PollLoop_Initialise
+0001b670 g DF .text 0000005c phHciNfc_PollLoop_Release
+0001b6cc g DF .text 000001dc phHciNfc_PollLoop_Cfg
+0001bd30 g DF .text 0000002c phHciNfc_ReaderA_Get_PipeID
+0001be24 g DF .text 00000130 phHciNfc_ReaderA_Info_Sequence
+0001bf54 g DF .text 00000078 phHciNfc_ReaderA_Auto_Activate
+0001bfcc g DF .text 0000006c phHciNfc_ReaderA_Set_DataRateMax
+0001c038 g DF .text 0000020c phHciNfc_Send_ReaderA_Command
+0001c244 g DF .text 00000044 phHciNfc_ReaderA_Cont_Activate
+0001c288 g DF .text 00000064 phHciNfc_ReaderA_Update_Info
+0001c2ec g DF .text 0000006c phHciNfc_ReaderA_App_Data
+0001c358 g DF .text 0000006c phHciNfc_ReaderA_Fwi_Sfgt
+0001c744 g DF .text 0000002c phHciNfc_ReaderB_Get_PipeID
+0001c7dc g DF .text 00000060 phHciNfc_ReaderB_Update_Info
+0001c890 g DF .text 00000170 phHciNfc_ReaderB_Info_Sequence
+0001ca00 g DF .text 0000007c phHciNfc_ReaderB_Set_AFI
+0001ca7c g DF .text 00000098 phHciNfc_ReaderB_Set_LayerData
+0001ce90 g DF .text 00000110 phHciNfc_ReaderMgmt_Info_Sequence
+0001cfa0 g DF .text 000000e0 phHciNfc_ReaderMgmt_Release
+0001d080 g DF .text 000000f0 phHciNfc_Send_RFReader_Event
+0001d2a0 g DF .text 000000e4 phHciNfc_ReaderMgmt_Disable_Discovery
+0001d384 g DF .text 00000188 phHciNfc_ReaderMgmt_Enable_Discovery
+0001d50c g DF .text 000001d4 phHciNfc_Send_RFReader_Command
+0001dd70 g DF .text 000000f0 phHciNfc_ReaderMgmt_UICC_Dispatch
+0001e048 g DF .text 00000138 phHciNfc_FSM_Validate
+0001e378 g DF .text 000003b0 phHciNfc_Initialise_Sequence
+0001f3dc g DF .text 00000154 phHciNfc_Connect_Sequence
+0001fb34 g DF .text 0000002c phHciNfc_SWP_Get_PipeID
+00020228 g DF .text 0000002c phHciNfc_WI_Get_PipeID
+00020320 g DF .text 00000058 phHciNfc_WI_Get_Default
+000204f4 g DF .text 000000a0 phLlcNfc_Release
+00023094 g DF .text 00000084 phLlcNfc_TimerUnInit
+00020c80 g DF .text 00000018 phLlcNfc_H_Frame_DeInit
+000414bc g DO .bss 00000001 g_release_flag
+00021c28 g DF .text 00000094 phLlcNfc_Interface_Read
+00021208 g DF .text 000000b8 phLlcNfc_H_CreateIFramePayload
+000213c8 g DF .text 00000098 phLlcNfc_H_StoreIFrame
+0002254c g DF .text 000000b4 phLlcNfc_Interface_Write
+00022820 g DF .text 00000144 phLlcNfc_StartTimers
+00020c3c g DF .text 00000044 phLlcNfc_H_Frame_Init
+00021bf4 g DF .text 00000034 phLlcNfc_Interface_Init
+000227b0 g DF .text 00000038 phLlcNfc_TimerInit
+000227e8 g DF .text 00000038 phLlcNfc_CreateTimers
+0002130c g DF .text 000000bc phLlcNfc_H_CreateUFramePayload
+00021b54 g DF .text 000000a0 phLlcNfc_Interface_Register
+00020c98 g DF .text 00000060 phLlcNfc_H_ComputeCrc
+00020cf8 g DF .text 000001e8 phLlcNfc_H_SendTimedOutIFrame
+00020ee0 g DF .text 0000014c phLlcNfc_H_SendUserIFrame
+0002102c g DF .text 000001dc phLlcNfc_H_SendRejectedIFrame
+000212c0 g DF .text 0000004c phLlcNfc_H_CreateSFramePayload
+00021460 g DF .text 000000bc phLlcNfc_H_SendRSETFrame
+0002151c g DF .text 000000a0 phLlcNfc_H_WriteWaitCall
+000215bc g DF .text 00000250 phLlcNfc_H_ProcessIFrame
+00022964 g DF .text 000001ac phLlcNfc_StopTimers
+00022600 g DF .text 000000e0 phLlcNfc_H_SendInfo
+0002180c g DF .text 00000348 phLlcNfc_H_ProRecvFrame
+00022d6c g DF .text 00000064 phLlcNfc_StopAllTimers
+000226e0 g DF .text 000000d0 phLlcNfc_H_ChangeState
+000411d0 g DO .bss 00000004 libnfc_llc_error_count
+00023048 g DF .text 0000004c phLlcNfc_DeleteTimer
+00024308 g DF .text 0000003c phFriNfc_Llcp_Header2Buffer
+00024344 g DF .text 0000001c phFriNfc_Llcp_Sequence2Buffer
+00028054 g DF .text 0000003c phFriNfc_LlcpMac_Send
+00028034 g DF .text 00000020 phFriNfc_LlcpMac_Deactivate
+00024360 g DF .text 00000058 phFriNfc_Llcp_Buffer2Header
+00023f78 g DF .text 00000088 phFriNfc_Llcp_DecodeTLV
+00024000 g DF .text 000000b0 phFriNfc_Llcp_EncodeTLV
+00028090 g DF .text 0000003c phFriNfc_LlcpMac_Receive
+00027f20 g DF .text 00000048 phFriNfc_LlcpMac_Reset
+00027f68 g DF .text 000000ac phFriNfc_LlcpMac_ChkLlcp
+00028014 g DF .text 00000020 phFriNfc_LlcpMac_Activate
+00023e60 g DF .text 000000ec phFriNfc_Llcp_Send
+00023f4c g DF .text 0000002c phFriNfc_Llcp_Recv
+000240b0 g DF .text 00000090 phFriNfc_Llcp_AppendTLV
+00024140 g DF .text 00000018 phFriNfc_Llcp_EncodeMIUX
+00024158 g DF .text 00000010 phFriNfc_Llcp_EncodeRW
+00024168 g DF .text 00000020 phFriNfc_Llcp_CyclicFifoInit
+00024188 g DF .text 00000018 phFriNfc_Llcp_CyclicFifoClear
+000241a0 g DF .text 0000006c phFriNfc_Llcp_CyclicFifoWrite
+0002420c g DF .text 00000070 phFriNfc_Llcp_CyclicFifoFifoRead
+0002427c g DF .text 0000004c phFriNfc_Llcp_CyclicFifoUsage
+000242c8 g DF .text 00000040 phFriNfc_Llcp_CyclicFifoAvailable
+000243b8 g DF .text 00000034 phFriNfc_Llcp_Buffer2Sequence
+00027098 g DF .text 00000e88 Handle_ConnectionOriented_IncommingFrame
+00025cd0 g DF .text 000000f8 Handle_Connectionless_IncommingFrame
+00024bf4 g DF .text 0000006c phFriNfc_LlcpTransport_LinkSend
+00024c60 g DF .text 00000180 phFriNfc_LlcpTransport_SendFrameReject
+00026cf8 g DF .text 000000b8 phFriNfc_LlcpTransport_ConnectionOriented_Close
+00024de0 g DF .text 000000b0 phFriNfc_LlcpTransport_SendDisconnectMode
+00026540 g DF .text 0000025c phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations
+00025c48 g DF .text 00000088 phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations
+0002679c g DF .text 0000001c phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions
+000267b8 g DF .text 0000001c phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions
+00000000 DF *UND* 00000000 __aeabi_uidiv
+00025dc8 g DF .text 000000f0 phFriNfc_LlcpTransport_Connectionless_Close
+000267d4 g DF .text 00000024 phFriNfc_LlcpTransport_ConnectionOriented_Listen
+000267f8 g DF .text 0000021c phFriNfc_LlcpTransport_ConnectionOriented_Accept
+00026a14 g DF .text 0000003c phLibNfc_LlcpTransport_ConnectionOriented_Reject
+00026a50 g DF .text 0000018c phFriNfc_LlcpTransport_ConnectionOriented_Connect
+00026bdc g DF .text 0000011c phLibNfc_LlcpTransport_ConnectionOriented_Disconnect
+00026db0 g DF .text 000000ac phFriNfc_LlcpTransport_ConnectionOriented_Send
+00026e5c g DF .text 0000023c phFriNfc_LlcpTransport_ConnectionOriented_Recv
+00025eb8 g DF .text 000000a4 phFriNfc_LlcpTransport_Connectionless_SendTo
+00025f5c g DF .text 000000bc phLibNfc_LlcpTransport_Connectionless_RecvFrom
+00000000 DF *UND* 00000000 __aeabi_uidivmod
+00026510 g DF .text 00000030 phFriNfc_LlcpConnTransport_Send
+00028678 g DF .text 0000006c phFriNfc_LlcpMac_Nfcip_Register
+0003b9d8 g DF .text 00000164 phFriNfc_OvrHal_Transceive
+0003bb3c g DF .text 0000008c phFriNfc_OvrHal_Receive
+0003bbc8 g DF .text 00000088 phFriNfc_OvrHal_Send
+00037794 g DF .text 000000bc phFriNfc_NdefMap_Process
+00029cac g DF .text 00000a30 phFriNfc_Felica_Process
+000316f0 g DF .text 00000090 phFriNfc_MapTool_ChkSpcVer
+00031644 g DF .text 000000ac phFriNfc_MapTool_SetCardState
+0002a6dc g DF .text 00000108 phFriNfc_Felica_RdNdef
+0002a7e4 g DF .text 00000064 phFriNfc_Felica_WrNdef
+0002a848 g DF .text 0000004c phFriNfc_Felica_EraseNdef
+0002a894 g DF .text 000000c4 phFriNfc_Felica_ChkNdef
+0002c7f0 g DF .text 00002158 phFriNfc_MifareStdMap_Process
+0002c588 g DF .text 000000e0 phFriNfc_MifareStdMap_H_Reset
+0002c668 g DF .text 00000188 phFriNfc_MifareStdMap_ChkNdef
+0003bc50 g DF .text 00000064 phFriNfc_OvrHal_Reconnect
+0003bcb4 g DF .text 00000068 phFriNfc_OvrHal_Connect
+0002e948 g DF .text 0000011c phFriNfc_MifareStdMap_RdNdef
+0002ea64 g DF .text 00000188 phFriNfc_MifareStdMap_WrNdef
+0002fca4 g DF .text 0000149c phFriNfc_MifareUL_Process
+00031140 g DF .text 000000c4 phFriNfc_MifareUL_H_Reset
+00031204 g DF .text 00000200 phFriNfc_MifareUL_RdNdef
+00031404 g DF .text 0000016c phFriNfc_MifareUL_WrNdef
+00031570 g DF .text 000000d4 phFriNfc_MifareUL_ChkNdef
+00031f78 g DF .text 00000994 phFriNfc_TopazMap_Process
+00031b68 g DF .text 00000068 phFriNfc_TopazMap_H_Reset
+00031bd0 g DF .text 00000054 phFriNfc_TopazMap_ChkNdef
+00031c24 g DF .text 0000002c phFriNfc_TopazMap_ConvertToReadOnly
+00031c50 g DF .text 00000174 phFriNfc_TopazMap_RdNdef
+00031dc4 g DF .text 000000fc phFriNfc_TopazMap_WrNdef
+00031ec0 g DF .text 00000028 phFriNfc_Tpz_H_ChkSpcVer
+00032f58 g DF .text 00001b30 phFriNfc_TopazDynamicMap_Process
+00034a88 g DF .text 00000098 phFriNfc_TopazDynamicMap_ChkNdef
+00034b20 g DF .text 00000250 phFriNfc_TopazDynamicMap_RdNdef
+00034d70 g DF .text 00000058 phFriNfc_TopazDynamicMap_ConvertToReadOnly
+00034dc8 g DF .text 000000cc phFriNfc_TopazDynamicMap_WrNdef
+00035598 g DF .text 00000780 phFriNfc_Desfire_Process
+00035d18 g DF .text 0000006c phFriNfc_Desfire_RdNdef
+00035d84 g DF .text 0000006c phFriNfc_Desfire_WrNdef
+00035df0 g DF .text 00000014 phFriNfc_Desfire_ChkNdef
+000363d8 g DF .text 00000a30 phFriNfc_ISO15693_Process
+00036e08 g DF .text 000000f4 phFriNfc_ISO15693_ChkNdef
+00036efc g DF .text 00000134 phFriNfc_ISO15693_RdNdef
+00037030 g DF .text 000000fc phFriNfc_ISO15693_WrNdef
+0003712c g DF .text 00000030 phFriNfc_ISO15693_ConvertToReadOnly
+00037aec g DF .text 00000060 phFriNfc_NdefMap_SetCardState
+00037b4c g DF .text 00000030 phFriNfc_NdefMap_CheckSpecVersion
+00037b7c g DF .text 00000098 phFriNfc_NdefReg_Strnicmp
+00037dec g DF .text 00000028 phFriNfc_NdefReg_DispatchRecord
+00000000 DF *UND* 00000000 phFriNfc_NdefRecord_GetLength
+00000000 DF *UND* 00000000 strncmp
+0003b3e8 g DF .text 0000009c phFriNfc_NdefSmtCrd_Process
+00038a60 g DF .text 00000038 phFriNfc_Desfire_Reset
+00038a98 g DF .text 0000002c phFriNfc_Desfire_Format
+00038ac4 g DF .text 00000028 phFriNfc_Desfire_ConvertToReadOnly
+00038aec g DF .text 00000650 phFriNfc_Desf_Process
+0003b16c g DF .text 0000001c phFriNfc_SmtCrdFmt_HCrHandler
+000395c0 g DF .text 0000005c phFriNfc_MfUL_Reset
+0003961c g DF .text 0000005c phFriNfc_MfUL_Format
+00039678 g DF .text 0000001c phFriNfc_MfUL_ConvertToReadOnly
+00039694 g DF .text 00000928 phFriNfc_MfUL_Process
+0003a790 g DF .text 000000dc phFriNfc_MfStd_Reset
+0003a86c g DF .text 00000058 phFriNfc_MfStd_Format
+0003a8c4 g DF .text 000008a8 phFriNfc_MfStd_Process
+0003b858 g DF .text 0000002c phFriNfc_ISO15693_FmtReset
+0003b884 g DF .text 0000003c phFriNfc_ISO15693_Format
+0003b5f8 g DF .text 00000260 phFriNfc_ISO15693_FmtProcess
+0003bd20 g DF .text 0000008c phOsalNfc_Timer_DeferredCall
+00000000 DF *UND* 00000000 printf
+00000000 DF *UND* 00000000 timer_create
+00000000 DF *UND* 00000000 timer_settime
+0003ddb0 g DF .text 000000d0 phDal4Nfc_msgsnd
+000413b8 g DO .bss 00000004 nDeferedCallMessageQueueId
+00000000 DF *UND* 00000000 timer_delete
+00000000 DF *UND* 00000000 malloc
+00000000 DF *UND* 00000000 free
+0003c0f8 g DF .text 00000004 phOsalNfc_DbgString
+0003c0f8 g DF .text 00000004 phOsalNfc_DbgTrace
+00000000 DF *UND* 00000000 abort
+0003c110 g DF .text 0000025c phOsalNfc_PrintData
+00000000 DF *UND* 00000000 snprintf
+00000000 DF *UND* 00000000 strcmp
+000414ac g DO .bss 00000008 phOsalNfc_Exception
+0003c3b8 g DF .text 00000018 phDal4Nfc_uart_initialize
+0003c3d0 g DF .text 00000020 phDal4Nfc_uart_set_open_from_handle
+0003c3f0 g DF .text 00000014 phDal4Nfc_uart_is_opened
+0003c404 g DF .text 00000018 phDal4Nfc_uart_flush
+00000000 DF *UND* 00000000 ioctl
+0003c41c g DF .text 00000034 phDal4Nfc_uart_close
+00000000 DF *UND* 00000000 close
+0003c450 g DF .text 0000010c phDal4Nfc_uart_open_and_configure
+00000000 DF *UND* 00000000 time
+00000000 DF *UND* 00000000 srand48
+00000000 DF *UND* 00000000 open
+00000000 DF *UND* 00000000 fcntl
+0003c55c g DF .text 000003c0 phDal4Nfc_uart_read
+00000000 DF *UND* 00000000 property_get
+00000000 DF *UND* 00000000 atoi
+00000000 DF *UND* 00000000 clock_gettime
+00000000 DF *UND* 00000000 select
+00000000 DF *UND* 00000000 read
+00000000 DF *UND* 00000000 lrand48
+00000000 DF *UND* 00000000 __errno
+0003c91c g DF .text 00000078 phDal4Nfc_uart_write
+00000000 DF *UND* 00000000 write
+0003c994 g DF .text 00000178 phDal4Nfc_uart_reset
+00000000 DF *UND* 00000000 strerror
+000413ac g DO .bss 00000004 property_error_rate
+0003cb0c g DF .text 00000040 phDal4Nfc_Shutdown
+0003cb4c g DF .text 00000008 phDal4Nfc_ReadWait
+0003cb54 g DF .text 0000001c phDal4Nfc_ReadWaitCancel
+00000000 DF *UND* 00000000 sem_post
+0003ce70 g DF .text 00000094 phDal4Nfc_Read
+0003d4b4 g DF .text 0000017c phDal4Nfc_Init
+0003d950 g DF .text 000000e4 phDal4Nfc_Write
+00000000 DF *UND* 00000000 pthread_join
+00000000 DF *UND* 00000000 hw_get_module
+00000000 DF *UND* 00000000 sem_init
+00000000 DF *UND* 00000000 pthread_create
+0003d6f8 g DF .text 00000258 phDal4Nfc_ReaderThread
+0003da34 g DF .text 0000001c phDal4Nfc_i2c_initialize
+0003da50 g DF .text 00000020 phDal4Nfc_i2c_set_open_from_handle
+0003da70 g DF .text 00000014 phDal4Nfc_i2c_is_opened
+0003da84 g DF .text 00000004 phDal4Nfc_i2c_flush
+0003da88 g DF .text 00000034 phDal4Nfc_i2c_close
+0003dabc g DF .text 0000004c phDal4Nfc_i2c_open_and_configure
+0003db08 g DF .text 000000e8 phDal4Nfc_i2c_read
+0003dbf0 g DF .text 00000078 phDal4Nfc_i2c_write
+0003dc68 g DF .text 0000001c phDal4Nfc_i2c_reset
+0003d67c g DF .text 0000007c phDal4Nfc_DeferredCall
+00000000 DF *UND* 00000000 pthread_self
+00000000 DF *UND* 00000000 pthread_setname_np
+00000000 DF *UND* 00000000 sem_wait
+0003dc84 g DF .text 00000088 phDal4Nfc_msgget
+00000000 DF *UND* 00000000 pthread_mutex_init
+0003dd0c g DF .text 000000a4 phDal4Nfc_msgctl
+00000000 DF *UND* 00000000 pthread_mutex_lock
+00000000 DF *UND* 00000000 pthread_mutex_unlock
+00000000 DF *UND* 00000000 pthread_mutex_destroy
+0003de80 g DF .text 0000007c phDal4Nfc_msgrcv
+0003defc g DF .text 0000000c __on_dlclose
+00000000 DF *UND* 00000000 __cxa_finalize
+00041470 g D .bss 00000000 __dso_handle
+00040d50 g D .init_array 00000000 __INIT_ARRAY__
+00040d58 g D .fini_array 00000000 __FINI_ARRAY__
+00041040 g D *ABS* 00000000 _edata
+00041040 g D *ABS* 00000000 __bss_start
+000414bd g D *ABS* 00000000 _end
+
+
|
[-]
[+]
|
Added |
_service:tar_git:libhybris-0.0.5.34.tar.bz2/libhybris/utils/generate_nfc/symbols/libnfc_ndef.so.txt
^
|
@@ -0,0 +1,19 @@
+
+libnfc_ndef.so: file format elf32-little
+
+DYNAMIC SYMBOL TABLE:
+00000000 DF *UND* 00000000 __aeabi_unwind_cpp_pr0
+000004a7 g DF .text 000001ee phFriNfc_NdefRecord_GetRecords
+00000695 g DF .text 00000050 phFriNfc_NdefRecord_GetLength
+000006e5 g DF .text 000000e8 phFriNfc_NdefRecord_Parse
+000007cd g DF .text 00000146 phFriNfc_NdefRecord_Generate
+00000914 g DF .text 0000000c __on_dlclose
+00000000 DF *UND* 00000000 __cxa_finalize
+00002000 g D .bss 00000000 __dso_handle
+00001ed4 g D .init_array 00000000 __INIT_ARRAY__
+00001edc g D .fini_array 00000000 __FINI_ARRAY__
+00002000 g D *ABS* 00000000 _edata
+00002000 g D *ABS* 00000000 __bss_start
+00002010 g D *ABS* 00000000 _end
+
+
|