提交 003496e3 编写于 作者: D dhy308

Fix code review issues.

Issue: I6A9R5
Test: libc-test pass
Signed-off-by: Ndhy308 <tony.gan@huawei.com>
上级 9b9fbfb5
# Copyright (c) 2022 Huawei Device Co., Ltd. # Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
...@@ -22,8 +22,6 @@ group("ldso_cfi_test") { ...@@ -22,8 +22,6 @@ group("ldso_cfi_test") {
} }
ohos_executable("ldso_cfi_check") { ohos_executable("ldso_cfi_check") {
# cflags_c = ["--coverage"]
# ldflags = ["--coverage"]
subsystem_name = "musl" subsystem_name = "musl"
part_name = "libc-test" part_name = "libc-test"
include_dirs = [ include_dirs = [
...@@ -41,8 +39,6 @@ ohos_shared_library("ldso_cfi_test_lib") { ...@@ -41,8 +39,6 @@ ohos_shared_library("ldso_cfi_test_lib") {
include_dirs = [ "." ] include_dirs = [ "." ]
sources = [ "ldso_cfi_test_lib.c" ] sources = [ "ldso_cfi_test_lib.c" ]
# cflags_c = ["--coverage"]
# ldflags = ["--coverage"]
output_name = "ldso_cfi_test_lib" output_name = "ldso_cfi_test_lib"
output_extension = "so" output_extension = "so"
subsystem_name = "musl" subsystem_name = "musl"
......
/** /**
* Copyright (c) 2022 Huawei Device Co., Ltd. * Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
struct dso { struct dso {
char *mock; char *mock;
unsigned char *map;
size_t map_len;
}; };
extern bool init_cfi_shadow(struct dso *dso_list); extern int init_cfi_shadow(struct dso *dso_list);
extern bool map_dso_to_cfi_shadow(struct dso *dso); extern int map_dso_to_cfi_shadow(struct dso *dso);
extern void unmap_dso_from_cfi_shadow(struct dso *dso); extern void unmap_dso_from_cfi_shadow(struct dso *dso);
extern void __cfi_slowpath(uint64_t CallSiteTypeId, void *Ptr); extern void __cfi_slowpath(uint64_t CallSiteTypeId, void *Ptr);
extern void __cfi_slowpath_diag(uint64_t CallSiteTypeId, void *Ptr, void *DiagData); extern void __cfi_slowpath_diag(uint64_t CallSiteTypeId, void *Ptr, void *DiagData);
...@@ -60,7 +62,7 @@ static void test_func() {} ...@@ -60,7 +62,7 @@ static void test_func() {}
void cfi_init_test_0001(void) void cfi_init_test_0001(void)
{ {
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__); printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
EXPECT_TRUE("cfi_init_test_0001", init_cfi_shadow(NULL)); EXPECT_EQ("cfi_init_test_0001", init_cfi_shadow(NULL), 0);
} }
/** /**
...@@ -71,7 +73,7 @@ void cfi_init_test_0001(void) ...@@ -71,7 +73,7 @@ void cfi_init_test_0001(void)
void cfi_init_test_0002(void) void cfi_init_test_0002(void)
{ {
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__); printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
EXPECT_TRUE("cfi_init_test_0002", map_dso_to_cfi_shadow(NULL)); EXPECT_EQ("cfi_init_test_0002", map_dso_to_cfi_shadow(NULL), 0);
} }
/** /**
...@@ -320,6 +322,37 @@ void cfi_slowpath_diag_function_test_0001(void) ...@@ -320,6 +322,37 @@ void cfi_slowpath_diag_function_test_0001(void)
printf("["__FILE__"][Line: %d][%s]: end\n", __LINE__, __func__); printf("["__FILE__"][Line: %d][%s]: end\n", __LINE__, __func__);
} }
/**
* @tc.name : cfi_unmap_dso_from_cfi_shadow_001
* @tc.desc : If dso map is NULL while unmapping from the CFI shadow, do nothing.
* @tc.level : Level 2
*/
void cfi_unmap_dso_from_cfi_shadow_001(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
struct dso test_dso = {};
test_dso.map = 0;
test_dso.map_len = 1;
unmap_dso_from_cfi_shadow(&test_dso);
printf("["__FILE__"][Line: %d][%s]: end\n", __LINE__, __func__);
}
/**
* @tc.name : cfi_unmap_dso_from_cfi_shadow_002
* @tc.desc : If dso map_len is NULL while unmapping from the CFI shadow, do nothing.
* @tc.level : Level 2
*/
void cfi_unmap_dso_from_cfi_shadow_002(void)
{
printf("["__FILE__"][Line: %d][%s]: entry\n", __LINE__, __func__);
struct dso test_dso = {};
int a = 9;
test_dso.map = (unsigned char *)a;
test_dso.map_len = 0;
unmap_dso_from_cfi_shadow(&test_dso);
printf("["__FILE__"][Line: %d][%s]: end\n", __LINE__, __func__);
}
TEST_FUN G_Fun_Array[] = { TEST_FUN G_Fun_Array[] = {
cfi_init_test_0001, cfi_init_test_0001,
cfi_init_test_0002, cfi_init_test_0002,
...@@ -332,6 +365,8 @@ TEST_FUN G_Fun_Array[] = { ...@@ -332,6 +365,8 @@ TEST_FUN G_Fun_Array[] = {
cfi_slowpath_function_test_0007, cfi_slowpath_function_test_0007,
cfi_slowpath_function_test_0008, cfi_slowpath_function_test_0008,
cfi_slowpath_diag_function_test_0001, cfi_slowpath_diag_function_test_0001,
cfi_unmap_dso_from_cfi_shadow_001,
cfi_unmap_dso_from_cfi_shadow_002,
}; };
int main(void) int main(void)
......
/**
* Copyright (c) 2023 Huawei Device Co., 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 <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
......
/*
* Copyright (c) 2023 Huawei Device Co., 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.
*/
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/prctl.h> #include <sys/prctl.h>
...@@ -7,13 +22,48 @@ ...@@ -7,13 +22,48 @@
/* This module provides support for LLVM CFI Cross-DSO by implementing the __cfi_slowpath() and __cfi_slowpath_diag() /* This module provides support for LLVM CFI Cross-DSO by implementing the __cfi_slowpath() and __cfi_slowpath_diag()
* functions. These two functions will be called before visiting other dso's resources. The responsibility is to * functions. These two functions will be called before visiting other dso's resources. The responsibility is to
* calculate the __cfi_check() of the target dso, and call it. * calculate the __cfi_check() of the target dso, and call it. So use CFI shadow and shadow value to store the
* The relationship between __cfi_check and dso addr is: * relationship between dso and its __cfi_check addr while loading a dso. CFI shadow is an array which stores shadow
* __cfi_check = AlignDown(addr, shadow_alignment) + shadow_alignment - (shadow_value - 2) * 4096; * values. Shadow value is used to store the relationship. A shadow value can map 1 LIBRARY_ALIGNMENT memory range. So
* The shadow_alignment presents the size of memory mapped by one shadow value. * each dso will be mapped to one or more shadow values in the CFI shadow, this depends on the address range of the
* The shadow_value presents the distance between the __cfi_check() and the the end address of each shadow alignment * dso.
* in the dso. It can be presented as a multiple of 4096. * There are 3 types for shadow value:
* The CFI shadow is used to store shadow value(s) of each dso. * - invalid(0) : the target addr does not belongs to any loaded dso.
* - uncheck(1) : this LIBRARY_ALIGNMENT memory range belongs to a dso but it is no need to do the CFI check.
* - valid(2 - 0xFFFF) : this LIBRARY_ALIGNMENT memory range belongs to a dso and need to do the CFI check.
* The valid shadow value records the distance from the end of a LIBRARY_ALIGNMENT memory range to the __cfi_check addr
* of the dso (The unit is 4096, because the __cfi_check is aligned with 4096).
* The valid shadow value is calculated as below:
* sv = (AlignUp(__cfi_check, LIBRARY_ALIGNMENT) - cfi_check_addr + N * LIBRARY_ALIGNMENT) / 4096 + 2;
*
* N : starts at 0, is the index of LIBRARY_ALIGNMENT memory range that belongs to a dso.
* + 2 : to avoid conflict with invalid and uncheck shadow value.
*
* Below is a example for calculating shadow values of a dso.
* liba.so
* /\
* /'''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''\
* 0x40000 __cfi_check addr = 0x42000 0x80000 0xA0000 0xC0000
* +---------^----------------------------------------^-------------------------^-------------------------+
* Memory | | | | |
* +------------------------------------------------------------------------------------------------------+
* \........... LIBRARY_ALIGNMENT ..................../\........... LIBRARY_ALIGNMENT ..................../ /
* \ / /
* \ / /
* \ / /
* \ / /
* \ / /
* +-----------------------------------------------------------------------------------------------------+
* CFI shadow | invalid | sv1 | sv2 | invalid |
* +-----------------------------------------------------------------------------------------------------+
* sv1 = (0x80000 - 0x42000 + 0 * LIBRARY_ALIGNMENT) / 4096 + 2 = 64
* sv2 = (0x80000 - 0x42000 + 1 * LIBRARY_ALIGNMENT) / 4096 + 2 = 126
*
* Calculating the __cfi_check address is a reverse process:
* - First align up the target addr with LIBRARY_ALIGNMENT to locate the corresponding shadow value.
* - Then calculate the __cfi_check addr.
*
* In order for the algorithm to work well, the start addr of each dso should be aligned with LIBRARY_ALIGNMENT.
*/ */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b))
...@@ -39,8 +89,20 @@ static char *cfi_shadow_start = NULL; ...@@ -39,8 +89,20 @@ static char *cfi_shadow_start = NULL;
static struct dso *dso_list_head = NULL; static struct dso *dso_list_head = NULL;
/* Shadow value */ /* Shadow value */
/* The related shadow value(s) will be set to `sv_invalid` when:
* - init CFI shadow.
* - removing a dso.
*/
static const uint16_t sv_invalid = 0; static const uint16_t sv_invalid = 0;
/* The related shadow value(s) will be set to `sv_uncheck` if:
* - the DSO does not enable CFI Cross-Dso.
* - the DSO enabled CFI Cross-Dso, but this DSO is larger than 16G, for the part of the dso that exceeds 16G,
* its shadow value will be set to `sv_uncheck`.
*/
static const uint16_t sv_uncheck = 1; static const uint16_t sv_uncheck = 1;
/* If a DSO enabled CFI Cross-Dso, the DSO's shadow value should be valid. Because of the defination of `sv_invalid`
* and `sv_unchecked`, the valid shadow value should be at least 2.
*/
static const uint16_t sv_valid_min = 2; static const uint16_t sv_valid_min = 2;
#if defined(__LP64__) #if defined(__LP64__)
...@@ -50,11 +112,11 @@ static const uintptr_t max_target_addr = 0xffffffff; ...@@ -50,11 +112,11 @@ static const uintptr_t max_target_addr = 0xffffffff;
#endif #endif
/* Create a cfi shadow */ /* Create a cfi shadow */
static bool create_cfi_shadow(void); static int create_cfi_shadow(void);
/* Map dsos to CFI shadow */ /* Map dsos to CFI shadow */
static bool add_dso_to_cfi_shadow(struct dso *dso); static int add_dso_to_cfi_shadow(struct dso *dso);
static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t cfi_check, uint16_t type); static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t cfi_check, uint16_t type);
/* Find the __cfi_check() of target dso and call it */ /* Find the __cfi_check() of target dso and call it */
void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr); void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr);
...@@ -68,37 +130,24 @@ static inline uintptr_t addr_to_offset(uintptr_t addr, int bits) ...@@ -68,37 +130,24 @@ static inline uintptr_t addr_to_offset(uintptr_t addr, int bits)
return (addr >> bits) << 1; return (addr >> bits) << 1;
} }
static void set_cfi_shadow_name()
{
LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
return;
}
static struct symdef find_cfi_check_sym(struct dso *p) static struct symdef find_cfi_check_sym(struct dso *p)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
if (p == NULL) {
LD_LOGE("[%{public}s] has null param!\n", __FUNCTION__);
struct symdef emptysym = {0};
return emptysym;
}
ns_t *ns = p->namespace;
struct verinfo verinfo = { .s = "__cfi_check", .v = "", .use_vna_hash = false }; struct verinfo verinfo = { .s = "__cfi_check", .v = "", .use_vna_hash = false };
return find_sym2(p, &verinfo, 0, 1, ns); struct sym_info_pair s_info_p = gnu_hash(verinfo.s);
return find_sym_impl(p, &verinfo, s_info_p, 0, p->namespace);
} }
static uintptr_t get_cfi_check_addr(uint16_t value, void* func_ptr) static uintptr_t get_cfi_check_addr(uint16_t value, void* func_ptr)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
uintptr_t addr = (uintptr_t)func_ptr; uintptr_t addr = (uintptr_t)func_ptr;
uintptr_t aligned_addr = ALIGN_DOWN(addr, shadow_alignment) + shadow_alignment; uintptr_t aligned_addr = ALIGN_DOWN(addr, shadow_alignment) + shadow_alignment;
uintptr_t cfi_check_func_addr = aligned_addr - ((uintptr_t)(value - sv_valid_min) << cfi_check_granularity); uintptr_t cfi_check_func_addr = aligned_addr - ((uintptr_t)(value - sv_valid_min) << cfi_check_granularity);
#ifdef __arm__ #ifdef __arm__
LD_LOGI("[%{public}s] __arm__ defined!\n", __FUNCTION__); LD_LOGD("[%{public}s] __arm__ defined!\n", __FUNCTION__);
cfi_check_func_addr++; cfi_check_func_addr++;
#endif #endif
LD_LOGI("[%{public}s] the cfi_check_func_addr is %{public}p!\n", __FUNCTION__, cfi_check_func_addr); LD_LOGI("[%{public}s] the cfi_check_func_addr is %{public}p!\n", __FUNCTION__, cfi_check_func_addr);
...@@ -108,21 +157,27 @@ static uintptr_t get_cfi_check_addr(uint16_t value, void* func_ptr) ...@@ -108,21 +157,27 @@ static uintptr_t get_cfi_check_addr(uint16_t value, void* func_ptr)
static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void *diag_data) static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void *diag_data)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGI("[%{public}s] func_ptr[%{public}p] !\n", __FUNCTION__, func_ptr); LD_LOGI("[%{public}s] func_ptr[%{public}p] !\n", __FUNCTION__, func_ptr);
uint16_t value = sv_invalid; uint16_t value = sv_invalid;
#if defined(__aarch64__) #if defined(__aarch64__)
LD_LOGI("[%{public}s] __aarch64__ defined!\n", __FUNCTION__); LD_LOGD("[%{public}s] __aarch64__ defined!\n", __FUNCTION__);
uintptr_t addr = (uintptr_t)func_ptr & ((1ULL << 56) - 1); uintptr_t addr = (uintptr_t)func_ptr & ((1ULL << 56) - 1);
#else #else
LD_LOGI("[%{public}s] __aarch64__ not defined!\n", __FUNCTION__); LD_LOGD("[%{public}s] __aarch64__ not defined!\n", __FUNCTION__);
uintptr_t addr = func_ptr; uintptr_t addr = func_ptr;
#endif #endif
/* Get shadow value */ /* Get shadow value */
uintptr_t offset = addr_to_offset(addr, shadow_granularity); uintptr_t offset = addr_to_offset(addr, shadow_granularity);
if (cfi_shadow_start == NULL) {
LD_LOGE("[%{public}s] the cfi_shadow_start is null!\n", __FUNCTION__);
__builtin_trap();
}
if (offset > shadow_size) { if (offset > shadow_size) {
value = sv_invalid; value = sv_invalid;
} else { } else {
...@@ -146,7 +201,7 @@ static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void ...@@ -146,7 +201,7 @@ static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void
LD_LOGE("[%{public}s] can not find the __cfi_check in the dso!\n", __FUNCTION__); LD_LOGE("[%{public}s] can not find the __cfi_check in the dso!\n", __FUNCTION__);
__builtin_trap(); __builtin_trap();
} }
LD_LOGI("[%{public}s] cfi_check addr[%{public}p]!\n", LD_LOGD("[%{public}s] cfi_check addr[%{public}p]!\n",
__FUNCTION__, LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value)); __FUNCTION__, LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value));
((cfi_check_t)LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value))(call_site_type_id, func_ptr, diag_data); ((cfi_check_t)LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value))(call_site_type_id, func_ptr, diag_data);
break; break;
...@@ -160,13 +215,13 @@ static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void ...@@ -160,13 +215,13 @@ static void cfi_slowpath_common(uint64_t call_site_type_id, void *func_ptr, void
return; return;
} }
bool init_cfi_shadow(struct dso *dso_list) int init_cfi_shadow(struct dso *dso_list)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
if (dso_list == NULL) { if (dso_list == NULL) {
LD_LOGW("[%{public}s] has null param!\n", __FUNCTION__); LD_LOGW("[%{public}s] has null param!\n", __FUNCTION__);
return true; return CFI_SUCCESS;
} }
/* Save the head node of dso list */ /* Save the head node of dso list */
...@@ -175,15 +230,15 @@ bool init_cfi_shadow(struct dso *dso_list) ...@@ -175,15 +230,15 @@ bool init_cfi_shadow(struct dso *dso_list)
return map_dso_to_cfi_shadow(dso_list); return map_dso_to_cfi_shadow(dso_list);
} }
bool map_dso_to_cfi_shadow(struct dso *dso) int map_dso_to_cfi_shadow(struct dso *dso)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
bool has_cfi_check = false; bool has_cfi_check = false;
if (dso == NULL) { if (dso == NULL) {
LD_LOGE("[%{public}s] has null param!\n", __FUNCTION__); LD_LOGW("[%{public}s] has null param!\n", __FUNCTION__);
return true; return CFI_SUCCESS;
} }
/* Find __cfi_check symbol in dso list */ /* Find __cfi_check symbol in dso list */
...@@ -198,27 +253,27 @@ bool map_dso_to_cfi_shadow(struct dso *dso) ...@@ -198,27 +253,27 @@ bool map_dso_to_cfi_shadow(struct dso *dso)
/* If the cfi shadow does not exist, create it and map all the dsos and its dependents to it. */ /* If the cfi shadow does not exist, create it and map all the dsos and its dependents to it. */
if (cfi_shadow_start == NULL) { if (cfi_shadow_start == NULL) {
if (has_cfi_check) { if (has_cfi_check) {
if (!create_cfi_shadow()) { if (create_cfi_shadow() == CFI_FAILED) {
LD_LOGE("[%{public}s] create cfi shadow failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] create cfi shadow failed!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
LD_LOGI("[%{public}s] add_dso_to_cfi_shadow with dso_list_head!\n", __FUNCTION__); LD_LOGD("[%{public}s] add_dso_to_cfi_shadow with dso_list_head!\n", __FUNCTION__);
add_dso_to_cfi_shadow(dso_list_head); add_dso_to_cfi_shadow(dso_list_head);
set_cfi_shadow_name(); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
} }
/* If the cfi shadow exists, map the current dso and its dependents to it. */ /* If the cfi shadow exists, map the current dso and its dependents to it. */
} else { } else {
LD_LOGI("[%{public}s] add_dso_to_cfi_shadow with dso!\n", __FUNCTION__); LD_LOGD("[%{public}s] add_dso_to_cfi_shadow with dso!\n", __FUNCTION__);
add_dso_to_cfi_shadow(dso); add_dso_to_cfi_shadow(dso);
set_cfi_shadow_name(); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
} }
return true; return CFI_SUCCESS;
} }
void unmap_dso_from_cfi_shadow(struct dso *dso) void unmap_dso_from_cfi_shadow(struct dso *dso)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
if (dso == NULL) { if (dso == NULL) {
LD_LOGE("[%{public}s] has null param!\n", __FUNCTION__); LD_LOGE("[%{public}s] has null param!\n", __FUNCTION__);
...@@ -233,16 +288,20 @@ void unmap_dso_from_cfi_shadow(struct dso *dso) ...@@ -233,16 +288,20 @@ void unmap_dso_from_cfi_shadow(struct dso *dso)
if (dso->map == 0 || dso->map_len == 0) if (dso->map == 0 || dso->map_len == 0)
return; return;
if (dso->is_mapped_to_shadow == false)
return;
/* Set the dso's shadow value as invalid. */ /* Set the dso's shadow value as invalid. */
fill_shadow_value_to_shadow(dso->map, dso->map + dso->map_len, 0, sv_invalid); fill_shadow_value_to_shadow(dso->map, dso->map + dso->map_len, 0, sv_invalid);
set_cfi_shadow_name(); dso->is_mapped_to_shadow = false;
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, cfi_shadow_start, shadow_size, "cfi_shadow:musl");
return; return;
} }
static bool create_cfi_shadow(void) static int create_cfi_shadow(void)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
/* Each process can load up to (max_target_addr >> shadow_granularity) dsos. Shift left 1 bit because the shadow /* Each process can load up to (max_target_addr >> shadow_granularity) dsos. Shift left 1 bit because the shadow
* value is uint16_t. The size passed to mmap() should be aligned with 4096, so shadow_size should be aligned. * value is uint16_t. The size passed to mmap() should be aligned with 4096, so shadow_size should be aligned.
...@@ -253,66 +312,67 @@ static bool create_cfi_shadow(void) ...@@ -253,66 +312,67 @@ static bool create_cfi_shadow(void)
if (mmap_addr == MAP_FAILED) { if (mmap_addr == MAP_FAILED) {
LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
cfi_shadow_start = (char*)mmap_addr; cfi_shadow_start = (char*)mmap_addr;
LD_LOGI("[%{public}s] the cfi_shadow_start addr is %{public}p!\n", __FUNCTION__, cfi_shadow_start); LD_LOGI("[%{public}s] the cfi_shadow_start addr is %{public}p!\n", __FUNCTION__, cfi_shadow_start);
return true; return CFI_SUCCESS;
} }
static bool add_dso_to_cfi_shadow(struct dso *dso) static int add_dso_to_cfi_shadow(struct dso *dso)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGI("[%{public}s] start!\n", __FUNCTION__);
for (struct dso *p = dso; p; p = p->next) { for (struct dso *p = dso; p; p = p->next) {
LD_LOGI("[%{public}s] start to deal with dso %{public}s!\n", __FUNCTION__, p->name); LD_LOGI("[%{public}s] start to deal with dso %{public}s!\n", __FUNCTION__, p->name);
if (p->map == 0 || p->map_len == 0) { if (p->map == 0 || p->map_len == 0) {
LD_LOGI("[%{public}s] the dso has no data!\n", __FUNCTION__); LD_LOGW("[%{public}s] the dso has no data!\n", __FUNCTION__);
continue;
}
if (p->is_mapped_to_shadow == true) {
LD_LOGW("[%{public}s] the dso is already in shadow!\n", __FUNCTION__);
continue; continue;
} }
struct symdef cfi_check_sym = find_cfi_check_sym(p); struct symdef cfi_check_sym = find_cfi_check_sym(p);
/* If the dso doesn't have __cfi_check(), set it's shadow value unchecked. */ /* If the dso doesn't have __cfi_check(), set it's shadow value unchecked. */
if (!cfi_check_sym.sym) { if (!cfi_check_sym.sym) {
LD_LOGI("[%{public}s] the dso has no __cfi_check func, call fill_shadow_value_to_shadow!\n", __FUNCTION__); LD_LOGI("[%{public}s] the dso has no __cfi_check()!\n", __FUNCTION__);
if (!fill_shadow_value_to_shadow(p->map, p->map + p->map_len, 0, sv_uncheck)) { if (fill_shadow_value_to_shadow(p->map, p->map + p->map_len, 0, sv_uncheck) == CFI_FAILED) {
LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
/* If the dso has __cfi_check(), set it's shadow value valid. */ /* If the dso has __cfi_check(), set it's shadow value valid. */
} else { } else {
LD_LOGI("[%{public}s] the dso has __cfi_check func,call fill_shadow_value_to_shadow!\n", __FUNCTION__); LD_LOGI("[%{public}s] the dso has __cfi_check()!\n", __FUNCTION__);
uintptr_t end = p->map + p->map_len; uintptr_t end = p->map + p->map_len;
uintptr_t cfi_check = LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value); uintptr_t cfi_check = LADDR(cfi_check_sym.dso, cfi_check_sym.sym->st_value);
if (cfi_check == 0) { if (cfi_check == 0) {
LD_LOGE("[%{public}s] the dso has null cfi_check func!\n", __FUNCTION__); LD_LOGE("[%{public}s] the dso has null cfi_check func!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
if (!fill_shadow_value_to_shadow(p->map, end, cfi_check, sv_valid_min)) { if (fill_shadow_value_to_shadow(p->map, end, cfi_check, sv_valid_min) == CFI_FAILED) {
LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] add dso to cfi shadow failed!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
} }
p->is_mapped_to_shadow = true;
LD_LOGI("[%{public}s] finish to deal with dso %{public}s!\n", __FUNCTION__, p->name); LD_LOGI("[%{public}s] finish to deal with dso %{public}s!\n", __FUNCTION__, p->name);
} }
return true; return CFI_SUCCESS;
} }
static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t cfi_check, uint16_t type) static int fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_t cfi_check, uint16_t type)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
LD_LOGI("[%{public}s] begin[%{public}x] end[%{public}x] cfi_check[%{public}x] type[%{public}x]!\n", LD_LOGI("[%{public}s] begin[%{public}x] end[%{public}x] cfi_check[%{public}x] type[%{public}x]!\n",
__FUNCTION__, begin, end, cfi_check, type); __FUNCTION__, begin, end, cfi_check, type);
if (begin == 0 || end == 0) {
LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__);
return false;
}
/* To ensure the atomicity of the CFI shadow operation, we create a temp_shadow, write the shadow value to /* To ensure the atomicity of the CFI shadow operation, we create a temp_shadow, write the shadow value to
* the temp_shadow, and then write it back to the CFI shadow by mremap().*/ * the temp_shadow, and then write it back to the CFI shadow by mremap().*/
begin = ALIGN_DOWN(MAX(begin, cfi_check), shadow_alignment); begin = ALIGN_DOWN(MAX(begin, cfi_check), shadow_alignment);
...@@ -330,10 +390,10 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_ ...@@ -330,10 +390,10 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_
if (tmp_shadow_start == MAP_FAILED) { if (tmp_shadow_start == MAP_FAILED) {
LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] mmap failed!\n", __FUNCTION__);
return false; return CFI_FAILED;
} }
LD_LOGI("[%{public}s] tmp_shadow_start is %{public}p\t tmp_shadow_size is 0x%{public}x!\n", LD_LOGD("[%{public}s] tmp_shadow_start is %{public}p\t tmp_shadow_size is 0x%{public}x!\n",
__FUNCTION__, tmp_shadow_start, tmp_shadow_size); __FUNCTION__, tmp_shadow_start, tmp_shadow_size);
memcpy(tmp_shadow_start, aligned_shadow_begin, offset_begin); memcpy(tmp_shadow_start, aligned_shadow_begin, offset_begin);
memcpy(tmp_shadow_start + offset_end, shadow_end, aligned_shadow_end - shadow_end); memcpy(tmp_shadow_start + offset_end, shadow_end, aligned_shadow_end - shadow_end);
...@@ -354,11 +414,14 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_ ...@@ -354,11 +414,14 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_
/* Set shadow_value */ /* Set shadow_value */
for (uint16_t *shadow_addr = tmp_shadow_start + offset_begin; for (uint16_t *shadow_addr = tmp_shadow_start + offset_begin;
shadow_addr != tmp_shadow_start + offset_end; shadow_addr++) { shadow_addr != tmp_shadow_start + offset_end; shadow_addr++) {
/* If a dso is larger than 16G( = max_shadow_value * shadow_alignment / 1G),
* the excess is not checked.
*/
if (shadow_value < shadow_value_begin) { if (shadow_value < shadow_value_begin) {
*shadow_addr = sv_uncheck; *shadow_addr = sv_uncheck;
continue; continue;
} }
*shadow_addr = shadow_value; *shadow_addr = (*shadow_addr == sv_invalid) ? shadow_value : sv_uncheck;
shadow_value += shadow_value_step; shadow_value += shadow_value_step;
} }
/* in these cases, shadow_value will always be sv_uncheck or sv_invalid */ /* in these cases, shadow_value will always be sv_uncheck or sv_invalid */
...@@ -370,7 +433,8 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_ ...@@ -370,7 +433,8 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_
} }
} else { } else {
LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__); LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__);
return false; munmap(tmp_shadow_start, tmp_shadow_size);
return CFI_FAILED;
} }
mprotect(tmp_shadow_start, tmp_shadow_size, PROT_READ); mprotect(tmp_shadow_start, tmp_shadow_size, PROT_READ);
...@@ -378,30 +442,25 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_ ...@@ -378,30 +442,25 @@ static bool fill_shadow_value_to_shadow(uintptr_t begin, uintptr_t end, uintptr_
uint16_t* mremap_addr = mremap(tmp_shadow_start, tmp_shadow_size, tmp_shadow_size, uint16_t* mremap_addr = mremap(tmp_shadow_start, tmp_shadow_size, tmp_shadow_size,
MREMAP_MAYMOVE | MREMAP_FIXED, aligned_shadow_begin); MREMAP_MAYMOVE | MREMAP_FIXED, aligned_shadow_begin);
if (mremap_addr == MAP_FAILED) if (mremap_addr == MAP_FAILED) {
{
LD_LOGE("[%{public}s] mremap failed!\n", __FUNCTION__); LD_LOGE("[%{public}s] mremap failed!\n", __FUNCTION__);
return false; munmap(tmp_shadow_start, tmp_shadow_size);
return CFI_FAILED;
} }
LD_LOGI("[%{public}s] fill completed!\n", __FUNCTION__); LD_LOGD("[%{public}s] fill completed!\n", __FUNCTION__);
return true; return CFI_SUCCESS;
} }
void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr) void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
if (func_ptr == NULL) { if (func_ptr == NULL) {
LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__); LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__);
return; return;
} }
if (cfi_shadow_start == NULL) {
LD_LOGE("[%{public}s] the cfi_shadow_start is null!\n", __FUNCTION__);
__builtin_trap();
}
cfi_slowpath_common(call_site_type_id, func_ptr, NULL); cfi_slowpath_common(call_site_type_id, func_ptr, NULL);
return; return;
...@@ -409,18 +468,13 @@ void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr) ...@@ -409,18 +468,13 @@ void __cfi_slowpath(uint64_t call_site_type_id, void *func_ptr)
void __cfi_slowpath_diag(uint64_t call_site_type_id, void *func_ptr, void *diag_data) void __cfi_slowpath_diag(uint64_t call_site_type_id, void *func_ptr, void *diag_data)
{ {
LD_LOGI("[%{public}s] start!\n", __FUNCTION__); LD_LOGD("[%{public}s] start!\n", __FUNCTION__);
if (func_ptr == NULL) { if (func_ptr == NULL) {
LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__); LD_LOGE("[%{public}s] has error param!\n", __FUNCTION__);
return; return;
} }
if (cfi_shadow_start == NULL) {
LD_LOGE("[%{public}s] the cfi_shadow_start is null!\n", __FUNCTION__);
__builtin_trap();
}
cfi_slowpath_common(call_site_type_id, func_ptr, diag_data); cfi_slowpath_common(call_site_type_id, func_ptr, diag_data);
return; return;
......
/*
* Copyright (c) 2023 Huawei Device Co., 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 "dynlink.h" #include "dynlink.h"
/* alignment bits in memory space for dso */ #define CFI_SUCCESS 0
#define CFI_FAILED -1
/* Define LIBRARY_ALIGNMENT to balance the size of CFI shadow and the number of DSOs that each process can load.
* The LIBRARY_ALIGNMENT is use to calculate the start address of a DSO. Each DSO should be in the different
* LIBRARY_ALIGNMENT memory range so that each DSO can be well mapped to the CFI shadow.
*/
#define LIBRARY_ALIGNMENT_BITS 18 #define LIBRARY_ALIGNMENT_BITS 18
/* minimum unit in memory space for dso */
#define LIBRARY_ALIGNMENT (1UL << LIBRARY_ALIGNMENT_BITS) #define LIBRARY_ALIGNMENT (1UL << LIBRARY_ALIGNMENT_BITS)
/* map all the dso and the dependents to cfi shadow */ /* map all the dso and the dependents to cfi shadow */
bool init_cfi_shadow(struct dso *dso_list); int init_cfi_shadow(struct dso *dso_list);
/* map a dso and the dependents to cfi shadow */ /* map a dso and the dependents to cfi shadow */
bool map_dso_to_cfi_shadow(struct dso *dso); int map_dso_to_cfi_shadow(struct dso *dso);
/* unmap a dso from cfi shadow */ /* unmap a dso from cfi shadow */
void unmap_dso_from_cfi_shadow(struct dso *dso); void unmap_dso_from_cfi_shadow(struct dso *dso);
\ No newline at end of file
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
#include <time.h> #include <time.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include "cfi.h"
#include "dlfcn_ext.h" #include "dlfcn_ext.h"
#include "dynlink_rand.h" #include "dynlink_rand.h"
#include "ld_log.h" #include "ld_log.h"
#include "cfi.h"
#include "libc.h" #include "libc.h"
#include "malloc_impl.h" #include "malloc_impl.h"
#include "namespace.h" #include "namespace.h"
...@@ -90,11 +90,6 @@ struct reserved_address_params { ...@@ -90,11 +90,6 @@ struct reserved_address_params {
#endif #endif
}; };
struct sym_info_pair {
uint_fast32_t sym_h;
uint32_t sym_l;
};
typedef void (*stage3_func)(size_t *, size_t *); typedef void (*stage3_func)(size_t *, size_t *);
static struct builtin_tls { static struct builtin_tls {
...@@ -491,7 +486,7 @@ static struct sym_info_pair sysv_hash(const char *s0) ...@@ -491,7 +486,7 @@ static struct sym_info_pair sysv_hash(const char *s0)
return s_info_p; return s_info_p;
} }
static struct sym_info_pair gnu_hash(const char *s0) struct sym_info_pair gnu_hash(const char *s0)
{ {
struct sym_info_pair s_info_p; struct sym_info_pair s_info_p;
const unsigned char *s = (void *)s0; const unsigned char *s = (void *)s0;
...@@ -706,7 +701,61 @@ static void add_can_search_so_list_in_dso(struct dso *dso_relocating, struct dso ...@@ -706,7 +701,61 @@ static void add_can_search_so_list_in_dso(struct dso *dso_relocating, struct dso
#if defined(__GNUC__) #if defined(__GNUC__)
__attribute__((always_inline)) __attribute__((always_inline))
#endif #endif
struct symdef find_sym2(struct dso *dso, struct verinfo *verinfo, int need_def, int use_deps, ns_t *ns)
struct symdef find_sym_impl(
struct dso *dso, struct verinfo *verinfo, struct sym_info_pair s_info_p, int need_def, ns_t *ns)
{
Sym *sym;
uint32_t *ght;
uint32_t h = 0;
uint32_t gh = s_info_p.sym_h;
uint32_t gho = gh / (8 * sizeof(size_t));
size_t ghm = 1ul << gh % (8 * sizeof(size_t));
struct symdef def = {0};
if (ns && !check_sym_accessible(dso, ns))
return def;
if ((ght = dso->ghashtab)) {
const size_t *bloomwords = (const void *)(ght + 4);
size_t f = bloomwords[gho & (ght[2] - 1)];
if (!(f & ghm))
return def;
f >>= (gh >> ght[3]) % (8 * sizeof f);
if (!(f & 1))
return def;
sym = gnu_lookup(s_info_p, ght, dso, verinfo);
} else {
if (!h)
s_info_p = sysv_hash(verinfo->s);
sym = sysv_lookup(verinfo, s_info_p, dso);
}
if (!sym)
return def;
if (!sym->st_shndx)
if (need_def || (sym->st_info & 0xf) == STT_TLS || ARCH_SYM_REJECT_UND(sym))
return def;
if (!sym->st_value)
if ((sym->st_info & 0xf) != STT_TLS)
return def;
if (!(1 << (sym->st_info & 0xf) & OK_TYPES))
return def;
if (!(1 << (sym->st_info >> 4) & OK_BINDS))
return def;
def.sym = sym;
def.dso = dso;
return def;
}
static inline struct symdef find_sym2(struct dso *dso, struct verinfo *verinfo, int need_def, int use_deps, ns_t *ns)
{ {
struct sym_info_pair s_info_p = gnu_hash(verinfo->s); struct sym_info_pair s_info_p = gnu_hash(verinfo->s);
uint32_t h = 0, gh = s_info_p.sym_h, gho = gh / (8*sizeof(size_t)), *ght; uint32_t h = 0, gh = s_info_p.sym_h, gho = gh / (8*sizeof(size_t)), *ght;
...@@ -2835,11 +2884,8 @@ void __dls3(size_t *sp, size_t *auxv) ...@@ -2835,11 +2884,8 @@ void __dls3(size_t *sp, size_t *auxv)
libc.tls_size = tmp_tls_size; libc.tls_size = tmp_tls_size;
} }
if (!init_cfi_shadow(head)) { if (init_cfi_shadow(head) == CFI_FAILED) {
error("[%s] init_cfi_shadow failed: %m", __FUNCTION__); error("[%s] init_cfi_shadow failed: %m", __FUNCTION__);
if (runtime) {
longjmp(*rtld_fail, 1);
}
} }
if (ldso_fail) _exit(127); if (ldso_fail) _exit(127);
...@@ -3142,11 +3188,9 @@ static void *dlopen_impl( ...@@ -3142,11 +3188,9 @@ static void *dlopen_impl(
* relocations resolved to symbol definitions that get removed. */ * relocations resolved to symbol definitions that get removed. */
redo_lazy_relocs(); redo_lazy_relocs();
if (!map_dso_to_cfi_shadow(p)) { if (map_dso_to_cfi_shadow(p) == CFI_FAILED) {
error("[%s] map_dso_to_cfi_shadow failed: %m", __FUNCTION__); error("[%s] map_dso_to_cfi_shadow failed: %m", __FUNCTION__);
if (runtime) { longjmp(*rtld_fail, 1);
longjmp(*rtld_fail, 1);
}
} }
if (mode & RTLD_NODELETE) { if (mode & RTLD_NODELETE) {
...@@ -4138,7 +4182,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para ...@@ -4138,7 +4182,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) ? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
: mmap((void *)start_addr, map_len, prot, map_flags, task->fd, off_start + task->file_offset); : mmap((void *)start_addr, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
if (map == MAP_FAILED) { if (map == MAP_FAILED) {
LD_LOGE("Error mapping library %{public}s: failed to map fd", task->name);
goto error; goto error;
} }
if (reserved_params && map_len < reserved_params->reserved_size) { if (reserved_params && map_len < reserved_params->reserved_size) {
...@@ -4150,7 +4193,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para ...@@ -4150,7 +4193,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
/* use tmp_map_len to mmap enough space for the dso with anonymous mapping */ /* use tmp_map_len to mmap enough space for the dso with anonymous mapping */
unsigned char *temp_map = mmap((void *)NULL, tmp_map_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); unsigned char *temp_map = mmap((void *)NULL, tmp_map_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (temp_map == MAP_FAILED) { if (temp_map == MAP_FAILED) {
LD_LOGE("Error mapping library 1 %{public}s: failed to map fd", task->name);
goto error; goto error;
} }
...@@ -4165,7 +4207,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para ...@@ -4165,7 +4207,6 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
/* use map_len to mmap correct space for the dso with file mapping */ /* use map_len to mmap correct space for the dso with file mapping */
: mmap(real_map, map_len, prot, map_flags, task->fd, off_start + task->file_offset); : mmap(real_map, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
if (map == MAP_FAILED) { if (map == MAP_FAILED) {
LD_LOGE("Error mapping library 3 %{public}s: failed to map fd", task->name);
goto error; goto error;
} }
} }
......
...@@ -58,6 +58,23 @@ enum { ...@@ -58,6 +58,23 @@ enum {
REL_FUNCDESC_VAL, REL_FUNCDESC_VAL,
}; };
struct td_index {
size_t args[2];
struct td_index *next;
};
struct verinfo {
const char *s;
const char *v;
bool use_vna_hash;
uint32_t vna_hash;
};
struct sym_info_pair {
uint_fast32_t sym_h;
uint32_t sym_l;
};
struct dso { struct dso {
#if DL_FDPIC #if DL_FDPIC
struct fdpic_loadmap *loadmap; struct fdpic_loadmap *loadmap;
...@@ -132,6 +149,7 @@ struct dso { ...@@ -132,6 +149,7 @@ struct dso {
struct dso **reloc_can_search_dso_list; struct dso **reloc_can_search_dso_list;
size_t reloc_can_search_dso_count; size_t reloc_can_search_dso_count;
size_t reloc_can_search_dso_capacity; size_t reloc_can_search_dso_capacity;
bool is_mapped_to_shadow;
char buf[]; char buf[];
}; };
...@@ -140,18 +158,6 @@ struct symdef { ...@@ -140,18 +158,6 @@ struct symdef {
struct dso *dso; struct dso *dso;
}; };
struct verinfo {
const char *s;
const char *v;
bool use_vna_hash;
uint32_t vna_hash;
};
struct td_index {
size_t args[2];
struct td_index *next;
};
struct fdpic_loadseg { struct fdpic_loadseg {
uintptr_t addr, p_vaddr, p_memsz; uintptr_t addr, p_vaddr, p_memsz;
}; };
...@@ -222,7 +228,9 @@ void *laddr(const struct dso *p, size_t v); ...@@ -222,7 +228,9 @@ void *laddr(const struct dso *p, size_t v);
#endif #endif
void *addr2dso(size_t a); void *addr2dso(size_t a);
struct symdef find_sym2(struct dso *dso, struct verinfo *verinfo, int need_def, int use_deps, ns_t *ns); struct sym_info_pair gnu_hash(const char *s0);
struct symdef find_sym_impl(
struct dso *dso, struct verinfo *verinfo, struct sym_info_pair s_info_p, int need_def, ns_t *ns);
hidden void *__dlsym(void *restrict, const char *restrict, void *restrict); hidden void *__dlsym(void *restrict, const char *restrict, void *restrict);
hidden void *__dlvsym(void *restrict, const char *restrict, const char *restrict, void *restrict); hidden void *__dlvsym(void *restrict, const char *restrict, const char *restrict, void *restrict);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册