Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Musl
提交
43df22c5
T
Third Party Musl
项目概览
OpenHarmony
/
Third Party Musl
接近 2 年 前同步成功
通知
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看板
未验证
提交
43df22c5
编写于
1月 13, 2023
作者:
O
openharmony_ci
提交者:
Gitee
1月 13, 2023
浏览文件
操作
浏览文件
下载
差异文件
!780 Support open uncompress library in zip file(pick 788 )
Merge pull request !780 from yinchuang/cherry-pick-1673402606
上级
ed460399
20db738a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
289 addition
and
19 deletion
+289
-19
porting/linux/user/ldso/dynlink.c
porting/linux/user/ldso/dynlink.c
+168
-19
porting/linux/user/ldso/dynlink_rand.h
porting/linux/user/ldso/dynlink_rand.h
+1
-0
porting/linux/user/ldso/zip_archive.h
porting/linux/user/ldso/zip_archive.h
+120
-0
未找到文件。
porting/linux/user/ldso/dynlink.c
浏览文件 @
43df22c5
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#ifdef OHOS_ENABLE_PARAMETER
#ifdef OHOS_ENABLE_PARAMETER
#include "sys_param.h"
#include "sys_param.h"
#endif
#endif
#include "zip_archive.h"
static
void
error
(
const
char
*
,
...);
static
void
error
(
const
char
*
,
...);
...
@@ -138,6 +139,7 @@ struct dso {
...
@@ -138,6 +139,7 @@ struct dso {
size_t
map_len
;
size_t
map_len
;
dev_t
dev
;
dev_t
dev
;
ino_t
ino
;
ino_t
ino
;
uint64_t
file_offset
;
char
relocated
;
char
relocated
;
char
constructed
;
char
constructed
;
char
kernel_mapped
;
char
kernel_mapped
;
...
@@ -1701,11 +1703,11 @@ static struct dso *search_dso_by_name(const char *name, const ns_t *ns) {
...
@@ -1701,11 +1703,11 @@ static struct dso *search_dso_by_name(const char *name, const ns_t *ns) {
return
NULL
;
return
NULL
;
}
}
static
struct
dso
*
search_dso_by_fstat
(
const
struct
stat
*
st
,
const
ns_t
*
ns
)
{
static
struct
dso
*
search_dso_by_fstat
(
const
struct
stat
*
st
,
const
ns_t
*
ns
,
uint64_t
file_offset
)
{
LD_LOGD
(
"search_dso_by_fstat ns_name:%{public}s"
,
ns
?
ns
->
ns_name
:
"NULL"
);
LD_LOGD
(
"search_dso_by_fstat ns_name:%{public}s"
,
ns
?
ns
->
ns_name
:
"NULL"
);
for
(
size_t
i
=
0
;
i
<
ns
->
ns_dsos
->
num
;
i
++
){
for
(
size_t
i
=
0
;
i
<
ns
->
ns_dsos
->
num
;
i
++
){
struct
dso
*
p
=
ns
->
ns_dsos
->
dsos
[
i
];
struct
dso
*
p
=
ns
->
ns_dsos
->
dsos
[
i
];
if
(
p
->
dev
==
st
->
st_dev
&&
p
->
ino
==
st
->
st_ino
)
{
if
(
p
->
dev
==
st
->
st_dev
&&
p
->
ino
==
st
->
st_ino
&&
p
->
file_offset
==
file_offset
)
{
LD_LOGD
(
"search_dso_by_fstat found dev:%{public}lu, ino:%{public}lu, ns_name:%{public}s"
,
LD_LOGD
(
"search_dso_by_fstat found dev:%{public}lu, ino:%{public}lu, ns_name:%{public}s"
,
st
->
st_dev
,
st
->
st_ino
,
ns
?
ns
->
ns_name
:
"NULL"
);
st
->
st_dev
,
st
->
st_ino
,
ns
?
ns
->
ns_name
:
"NULL"
);
return
p
;
return
p
;
...
@@ -1732,16 +1734,16 @@ static struct dso *find_library_by_name(const char *name, const ns_t *ns, bool c
...
@@ -1732,16 +1734,16 @@ static struct dso *find_library_by_name(const char *name, const ns_t *ns, bool c
return
NULL
;
return
NULL
;
}
}
/* Find loaded so by file stat */
/* Find loaded so by file stat */
static
struct
dso
*
find_library_by_fstat
(
const
struct
stat
*
st
,
const
ns_t
*
ns
,
bool
check_inherited
)
{
static
struct
dso
*
find_library_by_fstat
(
const
struct
stat
*
st
,
const
ns_t
*
ns
,
bool
check_inherited
,
uint64_t
file_offset
)
{
LD_LOGD
(
"find_library_by_fstat ns_name:%{public}s, check_inherited :%{public}d"
,
LD_LOGD
(
"find_library_by_fstat ns_name:%{public}s, check_inherited :%{public}d"
,
ns
?
ns
->
ns_name
:
"NULL"
,
ns
?
ns
->
ns_name
:
"NULL"
,
!!
check_inherited
);
!!
check_inherited
);
struct
dso
*
p
=
search_dso_by_fstat
(
st
,
ns
);
struct
dso
*
p
=
search_dso_by_fstat
(
st
,
ns
,
file_offset
);
if
(
p
)
return
p
;
if
(
p
)
return
p
;
if
(
check_inherited
&&
ns
->
ns_inherits
)
{
if
(
check_inherited
&&
ns
->
ns_inherits
)
{
for
(
size_t
i
=
0
;
i
<
ns
->
ns_inherits
->
num
;
i
++
){
for
(
size_t
i
=
0
;
i
<
ns
->
ns_inherits
->
num
;
i
++
){
ns_inherit
*
inherit
=
ns
->
ns_inherits
->
inherits
[
i
];
ns_inherit
*
inherit
=
ns
->
ns_inherits
->
inherits
[
i
];
p
=
search_dso_by_fstat
(
st
,
inherit
->
inherited_ns
);
p
=
search_dso_by_fstat
(
st
,
inherit
->
inherited_ns
,
file_offset
);
if
(
p
&&
is_sharable
(
inherit
,
p
->
shortname
))
return
p
;
if
(
p
&&
is_sharable
(
inherit
,
p
->
shortname
))
return
p
;
}
}
}
}
...
@@ -1873,7 +1875,7 @@ struct dso *load_library(
...
@@ -1873,7 +1875,7 @@ struct dso *load_library(
return
0
;
return
0
;
}
}
/* Search in namespace */
/* Search in namespace */
p
=
find_library_by_fstat
(
&
st
,
namespace
,
check_inherited
);
p
=
find_library_by_fstat
(
&
st
,
namespace
,
check_inherited
,
0
);
if
(
p
)
{
if
(
p
)
{
/* If this library was previously loaded with a
/* If this library was previously loaded with a
* pathname but a search found the same inode,
* pathname but a search found the same inode,
...
@@ -3994,7 +3996,7 @@ static bool map_library_header(struct loadtask *task)
...
@@ -3994,7 +3996,7 @@ static bool map_library_header(struct loadtask *task)
Phdr
*
ph
;
Phdr
*
ph
;
size_t
i
;
size_t
i
;
ssize_t
l
=
read
(
task
->
fd
,
task
->
ehdr_buf
,
sizeof
task
->
ehdr_buf
);
ssize_t
l
=
pread
(
task
->
fd
,
task
->
ehdr_buf
,
sizeof
task
->
ehdr_buf
,
task
->
file_offset
);
task
->
eh
=
task
->
ehdr_buf
;
task
->
eh
=
task
->
ehdr_buf
;
if
(
l
<
0
)
{
if
(
l
<
0
)
{
LD_LOGE
(
"Error mapping header %{public}s: failed to read fd"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to read fd"
,
task
->
name
);
...
@@ -4011,7 +4013,7 @@ static bool map_library_header(struct loadtask *task)
...
@@ -4011,7 +4013,7 @@ static bool map_library_header(struct loadtask *task)
LD_LOGE
(
"Error mapping header %{public}s: failed to alloc memory"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to alloc memory"
,
task
->
name
);
return
false
;
return
false
;
}
}
l
=
pread
(
task
->
fd
,
task
->
allocated_buf
,
task
->
phsize
,
task
->
eh
->
e_phoff
);
l
=
pread
(
task
->
fd
,
task
->
allocated_buf
,
task
->
phsize
,
task
->
eh
->
e_phoff
+
task
->
file_offset
);
if
(
l
<
0
)
{
if
(
l
<
0
)
{
LD_LOGE
(
"Error mapping header %{public}s: failed to pread"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to pread"
,
task
->
name
);
goto
error
;
goto
error
;
...
@@ -4022,7 +4024,7 @@ static bool map_library_header(struct loadtask *task)
...
@@ -4022,7 +4024,7 @@ static bool map_library_header(struct loadtask *task)
}
}
ph
=
task
->
ph0
=
task
->
allocated_buf
;
ph
=
task
->
ph0
=
task
->
allocated_buf
;
}
else
if
(
task
->
eh
->
e_phoff
+
task
->
phsize
>
l
)
{
}
else
if
(
task
->
eh
->
e_phoff
+
task
->
phsize
>
l
)
{
l
=
pread
(
task
->
fd
,
task
->
ehdr_buf
+
1
,
task
->
phsize
,
task
->
eh
->
e_phoff
);
l
=
pread
(
task
->
fd
,
task
->
ehdr_buf
+
1
,
task
->
phsize
,
task
->
eh
->
e_phoff
+
task
->
file_offset
);
if
(
l
<
0
)
{
if
(
l
<
0
)
{
LD_LOGE
(
"Error mapping header %{public}s: failed to pread"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to pread"
,
task
->
name
);
goto
error
;
goto
error
;
...
@@ -4052,7 +4054,10 @@ static bool map_library_header(struct loadtask *task)
...
@@ -4052,7 +4054,10 @@ static bool map_library_header(struct loadtask *task)
off_start
=
ph
->
p_offset
;
off_start
=
ph
->
p_offset
;
off_start
&=
-
PAGE_SIZE
;
off_start
&=
-
PAGE_SIZE
;
task
->
dyn_map_len
=
ph
->
p_memsz
+
(
ph
->
p_offset
-
off_start
);
task
->
dyn_map_len
=
ph
->
p_memsz
+
(
ph
->
p_offset
-
off_start
);
task
->
dyn_map
=
mmap
(
0
,
task
->
dyn_map_len
,
PROT_READ
,
MAP_PRIVATE
,
task
->
fd
,
off_start
);
/* The default value of file_offset is 0.
* The value of file_offset may be greater than 0 when opening library from zip file.
* The value of file_offset ensures PAGE_SIZE aligned. */
task
->
dyn_map
=
mmap
(
0
,
task
->
dyn_map_len
,
PROT_READ
,
MAP_PRIVATE
,
task
->
fd
,
off_start
+
task
->
file_offset
);
if
(
task
->
dyn_map
==
MAP_FAILED
)
{
if
(
task
->
dyn_map
==
MAP_FAILED
)
{
LD_LOGE
(
"Error mapping header %{public}s: failed to map dynamic section"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to map dynamic section"
,
task
->
name
);
goto
error
;
goto
error
;
...
@@ -4076,7 +4081,7 @@ static bool map_library_header(struct loadtask *task)
...
@@ -4076,7 +4081,7 @@ static bool map_library_header(struct loadtask *task)
off_start
=
str_table
;
off_start
=
str_table
;
off_start
&=
-
PAGE_SIZE
;
off_start
&=
-
PAGE_SIZE
;
task
->
str_map_len
=
str_size
+
(
str_table
-
off_start
);
task
->
str_map_len
=
str_size
+
(
str_table
-
off_start
);
task
->
str_map
=
mmap
(
0
,
task
->
str_map_len
,
PROT_READ
,
MAP_PRIVATE
,
task
->
fd
,
off_start
);
task
->
str_map
=
mmap
(
0
,
task
->
str_map_len
,
PROT_READ
,
MAP_PRIVATE
,
task
->
fd
,
off_start
+
task
->
file_offset
);
if
(
task
->
str_map
==
MAP_FAILED
)
{
if
(
task
->
str_map
==
MAP_FAILED
)
{
LD_LOGE
(
"Error mapping header %{public}s: failed to map string section"
,
task
->
name
);
LD_LOGE
(
"Error mapping header %{public}s: failed to map string section"
,
task
->
name
);
goto
error
;
goto
error
;
...
@@ -4154,7 +4159,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
...
@@ -4154,7 +4159,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
((
ph
->
p_flags
&
PF_X
)
?
PROT_EXEC
:
0
));
((
ph
->
p_flags
&
PF_X
)
?
PROT_EXEC
:
0
));
map
=
mmap
(
0
,
ph
->
p_memsz
+
(
ph
->
p_vaddr
&
PAGE_SIZE
-
1
),
map
=
mmap
(
0
,
ph
->
p_memsz
+
(
ph
->
p_vaddr
&
PAGE_SIZE
-
1
),
prot
,
MAP_PRIVATE
,
prot
,
MAP_PRIVATE
,
task
->
fd
,
ph
->
p_offset
&
-
PAGE_SIZE
);
task
->
fd
,
ph
->
p_offset
&
-
PAGE_SIZE
+
task
->
file_offset
);
if
(
map
==
MAP_FAILED
)
{
if
(
map
==
MAP_FAILED
)
{
unmap_library
(
task
->
p
);
unmap_library
(
task
->
p
);
goto
error
;
goto
error
;
...
@@ -4203,7 +4208,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
...
@@ -4203,7 +4208,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
* amount of virtual address space to map over later. */
* amount of virtual address space to map over later. */
map
=
DL_NOMMU_SUPPORT
map
=
DL_NOMMU_SUPPORT
?
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
);
:
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
);
LD_LOGE
(
"Error mapping library %{public}s: failed to map fd"
,
task
->
name
);
goto
error
;
goto
error
;
...
@@ -4253,7 +4258,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
...
@@ -4253,7 +4258,7 @@ static bool task_map_library(struct loadtask *task, struct reserved_address_para
this_max
-
this_min
,
this_max
-
this_min
,
prot
,
MAP_PRIVATE
|
MAP_FIXED
,
prot
,
MAP_PRIVATE
|
MAP_FIXED
,
task
->
fd
,
task
->
fd
,
off_start
)
==
MAP_FAILED
)
{
off_start
+
task
->
file_offset
)
==
MAP_FAILED
)
{
LD_LOGE
(
"Error mapping library %{public}s: mmap fix failed, errno: %{public}d"
,
task
->
name
,
errno
);
LD_LOGE
(
"Error mapping library %{public}s: mmap fix failed, errno: %{public}d"
,
task
->
name
,
errno
);
goto
error
;
goto
error
;
}
}
...
@@ -4309,6 +4314,7 @@ static bool load_library_header(struct loadtask *task)
...
@@ -4309,6 +4314,7 @@ static bool load_library_header(struct loadtask *task)
struct
dso
*
needed_by
=
task
->
needed_by
;
struct
dso
*
needed_by
=
task
->
needed_by
;
ns_t
*
namespace
=
task
->
namespace
;
ns_t
*
namespace
=
task
->
namespace
;
bool
check_inherited
=
task
->
check_inherited
;
bool
check_inherited
=
task
->
check_inherited
;
struct
zip_info
z_info
;
bool
map
=
false
;
bool
map
=
false
;
struct
stat
st
;
struct
stat
st
;
...
@@ -4364,11 +4370,30 @@ static bool load_library_header(struct loadtask *task)
...
@@ -4364,11 +4370,30 @@ static bool load_library_header(struct loadtask *task)
return
true
;
return
true
;
}
}
if
(
strchr
(
name
,
'/'
))
{
if
(
strchr
(
name
,
'/'
))
{
task
->
pathname
=
name
;
char
*
separator
=
strstr
(
name
,
ZIP_FILE_PATH_SEPARATOR
);
if
(
!
is_accessible
(
namespace
,
task
->
pathname
,
g_is_asan
,
check_inherited
))
{
if
(
separator
!=
NULL
)
{
task
->
fd
=
-
1
;
int
res
=
open_uncompressed_library_in_zipfile
(
name
,
&
z_info
,
separator
);
if
(
!
res
)
{
task
->
pathname
=
name
;
if
(
!
is_accessible
(
namespace
,
task
->
pathname
,
g_is_asan
,
check_inherited
))
{
LD_LOGE
(
"Open uncompressed library: check ns accessible failed, pathname %{public}s namespace %{public}s."
,
task
->
pathname
,
namespace
?
namespace
->
ns_name
:
"NULL"
);
task
->
fd
=
-
1
;
}
else
{
task
->
fd
=
z_info
.
fd
;
task
->
file_offset
=
z_info
.
file_offset
;
}
}
else
{
LD_LOGE
(
"Open uncompressed library in zip file failed, res = %{public}d"
,
res
);
return
false
;
}
}
else
{
}
else
{
task
->
fd
=
open
(
name
,
O_RDONLY
|
O_CLOEXEC
);
task
->
pathname
=
name
;
if
(
!
is_accessible
(
namespace
,
task
->
pathname
,
g_is_asan
,
check_inherited
))
{
task
->
fd
=
-
1
;
}
else
{
task
->
fd
=
open
(
name
,
O_RDONLY
|
O_CLOEXEC
);
}
}
}
}
else
{
}
else
{
/* Search for the name to see if it's already loaded */
/* Search for the name to see if it's already loaded */
...
@@ -4431,7 +4456,7 @@ static bool load_library_header(struct loadtask *task)
...
@@ -4431,7 +4456,7 @@ static bool load_library_header(struct loadtask *task)
return
false
;
return
false
;
}
}
/* Search in namespace */
/* Search in namespace */
task
->
p
=
find_library_by_fstat
(
&
st
,
namespace
,
check_inherited
);
task
->
p
=
find_library_by_fstat
(
&
st
,
namespace
,
check_inherited
,
task
->
file_offset
);
if
(
task
->
p
)
{
if
(
task
->
p
)
{
/* If this library was previously loaded with a
/* If this library was previously loaded with a
* pathname but a search found the same inode,
* pathname but a search found the same inode,
...
@@ -4477,6 +4502,7 @@ static bool load_library_header(struct loadtask *task)
...
@@ -4477,6 +4502,7 @@ static bool load_library_header(struct loadtask *task)
}
}
task
->
p
->
dev
=
st
.
st_dev
;
task
->
p
->
dev
=
st
.
st_dev
;
task
->
p
->
ino
=
st
.
st_ino
;
task
->
p
->
ino
=
st
.
st_ino
;
task
->
p
->
file_offset
=
task
->
file_offset
;
task
->
p
->
needed_by
=
needed_by
;
task
->
p
->
needed_by
=
needed_by
;
task
->
p
->
name
=
task
->
p
->
buf
;
task
->
p
->
name
=
task
->
p
->
buf
;
strcpy
(
task
->
p
->
name
,
task
->
pathname
);
strcpy
(
task
->
p
->
name
,
task
->
pathname
);
...
@@ -4864,3 +4890,126 @@ static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize
...
@@ -4864,3 +4890,126 @@ static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize
}
}
}
}
}
}
/* Used to get an uncompress library offset in zip file, then we can use the offset to mmap the library directly. */
int
open_uncompressed_library_in_zipfile
(
const
char
*
path
,
struct
zip_info
*
z_info
,
char
*
separator
)
{
struct
local_file_header
zip_file_header
;
struct
central_dir_entry
c_dir_entry
;
struct
zip_end_locator
end_locator
;
/* Use "'!/' to split the path into zipfile path and library path in zipfile.
* For example:
* - path: x/xx/xxx.zip!/x/xx/xxx.so
* - zipfile path: x/xx/xxx.zip
* - library path in zipfile: x/xx/xxx.so */
if
(
strlcpy
(
z_info
->
path_buf
,
path
,
PATH_BUF_SIZE
)
>=
PATH_BUF_SIZE
)
{
LD_LOGE
(
"Open uncompressed library: input path %{public}s is too long."
,
path
);
return
-
1
;
}
z_info
->
path_buf
[
separator
-
path
]
=
'\0'
;
z_info
->
file_path_index
=
separator
-
path
+
2
;
char
*
zip_file_path
=
z_info
->
path_buf
;
char
*
lib_path
=
&
z_info
->
path_buf
[
z_info
->
file_path_index
];
if
(
zip_file_path
==
NULL
||
lib_path
==
NULL
)
{
LD_LOGE
(
"Open uncompressed library: get zip and lib path failed."
);
return
-
1
;
}
LD_LOGD
(
"Open uncompressed library: zip file path %{public}s library path %{public}s."
,
zip_file_path
,
lib_path
);
// Get zip file length
FILE
*
zip_file
=
fopen
(
zip_file_path
,
"re"
);
if
(
zip_file
==
NULL
)
{
LD_LOGE
(
"Open uncompressed library: fopen %{public}s failed."
,
zip_file_path
);
return
-
1
;
}
if
(
fseek
(
zip_file
,
0
,
SEEK_END
)
!=
0
)
{
LD_LOGE
(
"Open uncompressed library: fseek SEEK_END failed."
);
fclose
(
zip_file
);
return
-
1
;
}
int64_t
zip_file_len
=
ftell
(
zip_file
);
if
(
zip_file_len
==
-
1
)
{
LD_LOGE
(
"Open uncompressed library: get zip file length failed."
);
fclose
(
zip_file
);
return
-
1
;
}
// Read end of central directory record.
size_t
end_locator_len
=
sizeof
(
end_locator
);
size_t
end_locator_pos
=
zip_file_len
-
end_locator_len
;
if
(
fseek
(
zip_file
,
end_locator_pos
,
SEEK_SET
)
!=
0
)
{
LD_LOGE
(
"Open uncompressed library: fseek end locator position failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
fread
(
&
end_locator
,
sizeof
(
end_locator
),
1
,
zip_file
)
!=
1
||
end_locator
.
signature
!=
EOCD_SIGNATURE
)
{
LD_LOGE
(
"Open uncompressed library: fread end locator failed."
);
fclose
(
zip_file
);
return
-
1
;
}
char
file_name
[
PATH_BUF_SIZE
];
uint64_t
current_dir_pos
=
end_locator
.
offset
;
for
(
uint16_t
i
=
0
;
i
<
end_locator
.
total_entries
;
i
++
)
{
// Read central dir entry.
if
(
fseek
(
zip_file
,
current_dir_pos
,
SEEK_SET
)
!=
0
)
{
LD_LOGE
(
"Open uncompressed library: fseek current centra dir entry position failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
fread
(
&
c_dir_entry
,
sizeof
(
c_dir_entry
),
1
,
zip_file
)
!=
1
||
c_dir_entry
.
signature
!=
CENTRAL_SIGNATURE
)
{
LD_LOGE
(
"Open uncompressed library: fread centra dir entry failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
fread
(
file_name
,
c_dir_entry
.
name_size
,
1
,
zip_file
)
!=
1
)
{
LD_LOGE
(
"Open uncompressed library: fread file name failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
strcmp
(
file_name
,
lib_path
)
==
0
)
{
// Read local file header.
if
(
fseek
(
zip_file
,
c_dir_entry
.
local_header_offset
,
SEEK_SET
)
!=
0
)
{
LD_LOGE
(
"Open uncompressed library: fseek local file header failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
fread
(
&
zip_file_header
,
sizeof
(
zip_file_header
),
1
,
zip_file
)
!=
1
)
{
LD_LOGE
(
"Open uncompressed library: fread local file header failed."
);
fclose
(
zip_file
);
return
-
1
;
}
if
(
zip_file_header
.
signature
!=
LOCAL_FILE_HEADER_SIGNATURE
)
{
LD_LOGE
(
"Open uncompressed library: read local file header signature error."
);
fclose
(
zip_file
);
return
-
1
;
}
z_info
->
file_offset
=
c_dir_entry
.
local_header_offset
+
sizeof
(
zip_file_header
)
+
zip_file_header
.
name_size
+
zip_file_header
.
extra_size
;
if
(
zip_file_header
.
compression_method
!=
COMPRESS_STORED
||
z_info
->
file_offset
%
PAGE_SIZE
!=
0
)
{
LD_LOGE
(
"Open uncompressed library: open %{public}s in %{public}s failed because of misalignment or saved with compression."
"compress method %{public}d, file offset %{public}lu"
,
lib_path
,
zip_file_path
,
zip_file_header
.
compression_method
,
z_info
->
file_offset
);
fclose
(
zip_file
);
return
-
2
;
}
z_info
->
found
=
true
;
break
;
}
memset
(
file_name
,
0
,
sizeof
(
file_name
));
current_dir_pos
+=
sizeof
(
c_dir_entry
);
current_dir_pos
+=
c_dir_entry
.
name_size
+
c_dir_entry
.
extra_size
+
c_dir_entry
.
comment_size
;
}
if
(
!
z_info
->
found
)
{
LD_LOGE
(
"Open uncompressed library: %{public}s was not found in %{public}s."
,
lib_path
,
zip_file_path
);
fclose
(
zip_file
);
return
-
3
;
}
z_info
->
fd
=
fileno
(
zip_file
);
return
0
;
}
\ No newline at end of file
porting/linux/user/ldso/dynlink_rand.h
浏览文件 @
43df22c5
...
@@ -46,6 +46,7 @@ struct loadtask {
...
@@ -46,6 +46,7 @@ struct loadtask {
const
char
*
pathname
;
const
char
*
pathname
;
struct
dso
*
p
;
struct
dso
*
p
;
int
fd
;
int
fd
;
uint64_t
file_offset
;
/* Used to read an uncompress library from a zip file, file_offset is relative offset of start of zip file. */
// variables for map library
// variables for map library
Ehdr
ehdr_buf
[(
READ_ELF_LENGTH
+
sizeof
(
Ehdr
))
/
sizeof
(
Ehdr
)];
Ehdr
ehdr_buf
[(
READ_ELF_LENGTH
+
sizeof
(
Ehdr
))
/
sizeof
(
Ehdr
)];
...
...
porting/linux/user/ldso/zip_archive.h
0 → 100644
浏览文件 @
43df22c5
/*
* 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.
*/
#ifndef _ZIP_ARCHIVE_H
#define _ZIP_ARCHIVE_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include <stdint.h>
#define PATH_BUF_SIZE 512
/* used for read zip file */
static
const
uint32_t
LOCAL_FILE_HEADER_SIGNATURE
=
0x04034b50
;
static
const
uint32_t
CENTRAL_SIGNATURE
=
0x02014b50
;
static
const
uint32_t
EOCD_SIGNATURE
=
0x06054b50
;
static
const
uint16_t
COMPRESS_STORED
=
0
;
static
const
char
*
ZIP_FILE_PATH_SEPARATOR
=
"!/"
;
struct
zip_info
{
int
fd
;
bool
found
;
uint64_t
file_offset
;
uint16_t
file_path_index
;
char
path_buf
[
PATH_BUF_SIZE
];
};
/* Zip Format:
* -------------------------------------------------------
* | Local file header 1 | |
* ----------------------------------- |
* | File data 1 | |
* ----------------------------------- |
* | Data descriptor 1 | |
* ----------------------------------- File Entry |
* | ... | |
* ----------------------------------- |
* | Local file header n | |
* ----------------------------------- |
* | File data n | |
* ----------------------------------- |
* | Data descriptor n | |
* -------------------------------------------------------
* | Central dir entry 1 | |
* ----------------------------------- |
* | ... | Central Directory |
* ----------------------------------- |
* | Central dir entry n | |
* -------------------------------------------------------
* | End of central directory record | EOCD |
* ------------------------------------------------------- */
// Local file header
struct
__attribute__
((
packed
))
local_file_header
{
uint32_t
signature
;
uint16_t
version_needed
;
uint16_t
flags
;
uint16_t
compression_method
;
uint16_t
modified_time
;
uint16_t
modified_date
;
uint32_t
crc
;
uint32_t
compressed_size
;
uint32_t
uncompressed_size
;
uint16_t
name_size
;
uint16_t
extra_size
;
};
// Central dir entry
struct
__attribute__
((
packed
))
central_dir_entry
{
uint32_t
signature
;
uint16_t
version_made
;
uint16_t
version_needed
;
uint16_t
flags
;
uint16_t
compression_method
;
uint16_t
modified_time
;
uint16_t
modified_date
;
uint32_t
crc
;
uint32_t
compressed_size
;
uint32_t
uncompressed_size
;
uint16_t
name_size
;
uint16_t
extra_size
;
uint16_t
comment_size
;
uint16_t
disk_num_start
;
uint16_t
internal_attr
;
uint32_t
external_attr
;
uint32_t
local_header_offset
;
};
// End of central directory record
struct
__attribute__
((
packed
))
zip_end_locator
{
uint32_t
signature
;
uint16_t
num_disk
;
uint16_t
start_disk_of_central_dir
;
uint16_t
total_entries_in_disk
;
uint16_t
total_entries
;
/* Total number of central directory entrys. */
uint32_t
size_of_central_dir
;
uint32_t
offset
;
/* Offset of start of central directory entry. */
uint16_t
comment_len
;
};
int
open_uncompressed_library_in_zipfile
(
const
char
*
path
,
struct
zip_info
*
z_info
,
char
*
separator
);
#ifdef __cplusplus
}
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录