Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Musl
提交
9959e363
T
Third Party Musl
项目概览
OpenHarmony
/
Third Party Musl
大约 1 年 前同步成功
通知
37
Star
125
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Musl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
9959e363
编写于
5月 17, 2023
作者:
O
openharmony_ci
提交者:
Gitee
5月 17, 2023
浏览文件
操作
浏览文件
下载
差异文件
!899 Optimize dladdr performance
Merge pull request !899 from yinchuang/opt_dladdr
上级
4ae0212f
f5e72894
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
91 addition
and
75 deletion
+91
-75
porting/linux/user/ldso/dynlink.c
porting/linux/user/ldso/dynlink.c
+91
-75
未找到文件。
porting/linux/user/ldso/dynlink.c
浏览文件 @
9959e363
...
...
@@ -105,7 +105,7 @@ struct reserved_address_params {
#endif
};
typedef
void
(
*
stage3_func
)(
size_t
*
,
size_t
*
);
typedef
void
(
*
stage3_func
)(
size_t
*
,
size_t
*
,
size_t
*
);
static
struct
builtin_tls
{
char
c
[
8
];
...
...
@@ -2609,6 +2609,9 @@ hidden void __dls2(unsigned char *base, size_t *sp)
}
else
{
ldso
.
base
=
base
;
}
size_t
aux
[
AUX_CNT
];
decode_vec
(
auxv
,
aux
,
AUX_CNT
);
libc
.
page_size
=
aux
[
AT_PAGESZ
];
Ehdr
*
ehdr
=
(
void
*
)
ldso
.
base
;
ldso
.
name
=
ldso
.
shortname
=
"libc.so"
;
ldso
.
phnum
=
ehdr
->
e_phnum
;
...
...
@@ -2645,8 +2648,8 @@ hidden void __dls2(unsigned char *base, size_t *sp)
* symbolically as a barrier against moving the address
* load across the above relocation processing. */
struct
symdef
dls2b_def
=
find_sym
(
&
ldso
,
"__dls2b"
,
0
);
if
(
DL_FDPIC
)
((
stage3_func
)
&
ldso
.
funcdescs
[
dls2b_def
.
sym
-
ldso
.
syms
])(
sp
,
auxv
);
else
((
stage3_func
)
laddr
(
&
ldso
,
dls2b_def
.
sym
->
st_value
))(
sp
,
auxv
);
if
(
DL_FDPIC
)
((
stage3_func
)
&
ldso
.
funcdescs
[
dls2b_def
.
sym
-
ldso
.
syms
])(
sp
,
auxv
,
aux
);
else
((
stage3_func
)
laddr
(
&
ldso
,
dls2b_def
.
sym
->
st_value
))(
sp
,
auxv
,
aux
);
}
/* Stage 2b sets up a valid thread pointer, which requires relocations
...
...
@@ -2655,7 +2658,7 @@ hidden void __dls2(unsigned char *base, size_t *sp)
* so that loads of the thread pointer and &errno can be pure/const and
* thereby hoistable. */
void
__dls2b
(
size_t
*
sp
,
size_t
*
auxv
)
void
__dls2b
(
size_t
*
sp
,
size_t
*
auxv
,
size_t
*
aux
)
{
/* Setup early thread pointer in builtin_tls for ldso/libc itself to
* use during dynamic linking. If possible it will also serve as the
...
...
@@ -2669,8 +2672,8 @@ void __dls2b(size_t *sp, size_t *auxv)
}
struct
symdef
dls3_def
=
find_sym
(
&
ldso
,
"__dls3"
,
0
);
if
(
DL_FDPIC
)
((
stage3_func
)
&
ldso
.
funcdescs
[
dls3_def
.
sym
-
ldso
.
syms
])(
sp
,
auxv
);
else
((
stage3_func
)
laddr
(
&
ldso
,
dls3_def
.
sym
->
st_value
))(
sp
,
auxv
);
if
(
DL_FDPIC
)
((
stage3_func
)
&
ldso
.
funcdescs
[
dls3_def
.
sym
-
ldso
.
syms
])(
sp
,
auxv
,
aux
);
else
((
stage3_func
)
laddr
(
&
ldso
,
dls3_def
.
sym
->
st_value
))(
sp
,
auxv
,
aux
);
}
/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
...
...
@@ -2678,10 +2681,9 @@ void __dls2b(size_t *sp, size_t *auxv)
* process dependencies and relocations for the main application and
* transfer control to its entry point. */
void
__dls3
(
size_t
*
sp
,
size_t
*
auxv
)
void
__dls3
(
size_t
*
sp
,
size_t
*
auxv
,
size_t
*
aux
)
{
static
struct
dso
app
,
vdso
;
size_t
aux
[
AUX_CNT
];
size_t
i
;
char
*
env_preload
=
0
;
char
*
replace_argv0
=
0
;
...
...
@@ -2694,10 +2696,8 @@ void __dls3(size_t *sp, size_t *auxv)
/* Find aux vector just past environ[] and use it to initialize
* global data that may be needed before we can make syscalls. */
__environ
=
envp
;
decode_vec
(
auxv
,
aux
,
AUX_CNT
);
search_vec
(
auxv
,
&
__sysinfo
,
AT_SYSINFO
);
__pthread_self
()
->
sysinfo
=
__sysinfo
;
libc
.
page_size
=
aux
[
AT_PAGESZ
];
libc
.
secure
=
((
aux
[
0
]
&
0x7800
)
!=
0x7800
||
aux
[
AT_UID
]
!=
aux
[
AT_EUID
]
||
aux
[
AT_GID
]
!=
aux
[
AT_EGID
]
||
aux
[
AT_SECURE
]);
...
...
@@ -3511,31 +3511,19 @@ void *addr2dso(size_t a)
{
struct
dso
*
p
;
size_t
i
;
if
(
DL_FDPIC
)
for
(
p
=
head
;
p
;
p
=
p
->
next
)
{
i
=
count_syms
(
p
);
if
(
a
-
(
size_t
)
p
->
funcdescs
<
i
*
sizeof
(
*
p
->
funcdescs
))
return
p
;
}
for
(
p
=
head
;
p
;
p
=
p
->
next
)
{
if
(
DL_FDPIC
&&
p
->
loadmap
)
{
for
(
i
=
0
;
i
<
p
->
loadmap
->
nsegs
;
i
++
)
{
if
(
a
-
p
->
loadmap
->
segs
[
i
].
p_vaddr
<
p
->
loadmap
->
segs
[
i
].
p_memsz
)
return
p
;
}
}
else
{
Phdr
*
ph
=
p
->
phdr
;
size_t
phcnt
=
p
->
phnum
;
size_t
entsz
=
p
->
phentsize
;
size_t
base
=
(
size_t
)
p
->
base
;
for
(;
phcnt
--
;
ph
=
(
void
*
)((
char
*
)
ph
+
entsz
))
{
if
(
ph
->
p_type
!=
PT_LOAD
)
continue
;
if
(
a
-
base
-
ph
->
p_vaddr
<
ph
->
p_memsz
)
return
p
;
}
if
(
a
-
(
size_t
)
p
->
map
<
p
->
map_len
)
return
0
;
if
(
a
<
p
->
map
||
a
-
(
size_t
)
p
->
map
>=
p
->
map_len
)
continue
;
Phdr
*
ph
=
p
->
phdr
;
size_t
phcnt
=
p
->
phnum
;
size_t
entsz
=
p
->
phentsize
;
size_t
base
=
(
size_t
)
p
->
base
;
for
(;
phcnt
--
;
ph
=
(
void
*
)((
char
*
)
ph
+
entsz
))
{
if
(
ph
->
p_type
!=
PT_LOAD
)
continue
;
if
(
a
-
base
-
ph
->
p_vaddr
<
ph
->
p_memsz
)
return
p
;
}
if
(
a
-
(
size_t
)
p
->
map
<
p
->
map_len
)
return
0
;
}
return
0
;
}
...
...
@@ -3777,15 +3765,71 @@ hidden int __dlclose(void *p)
return
rc
;
}
static
inline
int
sym_is_matched
(
const
Sym
*
sym
,
size_t
addr_offset_so
)
{
return
sym
->
st_value
&&
(
1
<<
(
sym
->
st_info
&
0xf
)
!=
STT_TLS
)
&&
(
addr_offset_so
>=
sym
->
st_value
)
&&
(
addr_offset_so
<
sym
->
st_value
+
sym
->
st_size
);
}
static
inline
Sym
*
find_addr_by_elf
(
size_t
addr_offset_so
,
struct
dso
*
p
)
{
uint32_t
nsym
=
p
->
hashtab
[
1
];
Sym
*
sym
=
p
->
syms
;
for
(;
nsym
;
nsym
--
,
sym
++
)
{
if
(
sym_is_matched
(
sym
,
addr_offset_so
))
{
return
sym
;
}
}
return
NULL
;
}
static
inline
Sym
*
find_addr_by_gnu
(
size_t
addr_offset_so
,
struct
dso
*
p
)
{
size_t
i
,
nsym
,
first_hash_sym_index
;
uint32_t
*
hashval
;
Sym
*
sym_tab
=
p
->
syms
;
uint32_t
*
buckets
=
p
->
ghashtab
+
4
+
(
p
->
ghashtab
[
2
]
*
sizeof
(
size_t
)
/
4
);
// Points to the first defined symbol, all symbols before it are undefined.
first_hash_sym_index
=
buckets
[
0
];
Sym
*
sym
=
&
sym_tab
[
first_hash_sym_index
];
// Get the location pointed by the last bucket.
for
(
i
=
nsym
=
0
;
i
<
p
->
ghashtab
[
0
];
i
++
)
{
if
(
buckets
[
i
]
>
nsym
)
nsym
=
buckets
[
i
];
}
for
(
i
=
first_hash_sym_index
;
i
<
nsym
;
i
++
)
{
if
(
sym_is_matched
(
sym
,
addr_offset_so
))
{
return
sym
;
}
sym
++
;
}
// Start traversing the hash list from the position pointed to by the last bucket.
if
(
nsym
)
{
hashval
=
buckets
+
p
->
ghashtab
[
0
]
+
(
nsym
-
p
->
ghashtab
[
1
]);
do
{
nsym
++
;
if
(
sym_is_matched
(
sym
,
addr_offset_so
))
{
return
sym
;
}
sym
++
;
}
while
(
!
(
*
hashval
++
&
1
));
}
return
NULL
;
}
int
dladdr
(
const
void
*
addr_arg
,
Dl_info
*
info
)
{
size_t
addr
=
(
size_t
)
addr_arg
;
struct
dso
*
p
;
Sym
*
sym
,
*
bestsym
;
uint32_t
nsym
;
Sym
*
match_sym
=
NULL
;
char
*
strings
;
size_t
best
=
0
;
size_t
besterr
=
-
1
;
pthread_rwlock_rdlock
(
&
lock
);
p
=
addr2dso
(
addr
);
...
...
@@ -3793,54 +3837,26 @@ int dladdr(const void *addr_arg, Dl_info *info)
if
(
!
p
)
return
0
;
sym
=
p
->
syms
;
strings
=
p
->
strings
;
nsym
=
count_syms
(
p
)
;
size_t
addr_offset_so
=
addr
-
(
size_t
)
p
->
base
;
if
(
DL_FDPIC
)
{
size_t
idx
=
(
addr
-
(
size_t
)
p
->
funcdescs
)
/
sizeof
(
*
p
->
funcdescs
);
if
(
idx
<
nsym
&&
(
sym
[
idx
].
st_info
&
0xf
)
==
STT_FUNC
)
{
best
=
(
size_t
)(
p
->
funcdescs
+
idx
);
bestsym
=
sym
+
idx
;
besterr
=
0
;
}
}
info
->
dli_fname
=
p
->
name
;
info
->
dli_fbase
=
p
->
map
;
if
(
!
best
)
for
(;
nsym
;
nsym
--
,
sym
++
)
{
if
(
sym
->
st_value
&&
(
1
<<
(
sym
->
st_info
&
0xf
)
&
OK_TYPES
)
&&
(
1
<<
(
sym
->
st_info
>>
4
)
&
OK_BINDS
))
{
size_t
symaddr
=
(
size_t
)
laddr
(
p
,
sym
->
st_value
);
if
(
symaddr
>
addr
||
symaddr
<=
best
)
continue
;
best
=
symaddr
;
bestsym
=
sym
;
besterr
=
addr
-
symaddr
;
if
(
addr
==
symaddr
)
break
;
}
}
if
(
p
->
ghashtab
)
{
match_sym
=
find_addr_by_gnu
(
addr_offset_so
,
p
);
if
(
best
&&
besterr
>
bestsym
->
st_size
-
1
)
{
best
=
0
;
bestsym
=
0
;
}
else
{
match_sym
=
find_addr_by_elf
(
addr_offset_so
,
p
);
}
info
->
dli_fname
=
p
->
name
;
info
->
dli_fbase
=
p
->
map
;
if
(
!
best
)
{
if
(
!
match_sym
)
{
info
->
dli_sname
=
0
;
info
->
dli_saddr
=
0
;
return
1
;
}
if
(
DL_FDPIC
&&
(
bestsym
->
st_info
&
0xf
)
==
STT_FUNC
)
best
=
(
size_t
)(
p
->
funcdescs
+
(
bestsym
-
p
->
syms
));
info
->
dli_sname
=
strings
+
bestsym
->
st_name
;
info
->
dli_saddr
=
(
void
*
)
best
;
info
->
dli_sname
=
strings
+
match_sym
->
st_name
;
info
->
dli_saddr
=
(
void
*
)
laddr
(
p
,
match_sym
->
st_value
);
return
1
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录